comfyui-frontend-package 1.38.5__py3-none-any.whl → 1.38.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- comfyui_frontend_package/static/assets/{AboutPanel-CHse5rOA.js → AboutPanel-lkjGFasi.js} +2 -2
- comfyui_frontend_package/static/assets/{AboutPanel-CHse5rOA.js.map → AboutPanel-lkjGFasi.js.map} +1 -1
- comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CAa8V66L.js → AudioPreviewPlayer-BxCSKPl9.js} +2 -2
- comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CAa8V66L.js.map → AudioPreviewPlayer-BxCSKPl9.js.map} +1 -1
- comfyui_frontend_package/static/assets/AudioPreviewPlayer-CkxKvcVf.js +1 -0
- comfyui_frontend_package/static/assets/{BaseViewTemplate-DA6zfigT.js → BaseViewTemplate-CjODF2hh.js} +2 -2
- comfyui_frontend_package/static/assets/{BaseViewTemplate-DA6zfigT.js.map → BaseViewTemplate-CjODF2hh.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudAuthTimeoutView-9OPBS1hE.js → CloudAuthTimeoutView-D-QkjPNh.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudAuthTimeoutView-9OPBS1hE.js.map → CloudAuthTimeoutView-D-QkjPNh.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudBadge-BnLiAHDN.js → CloudBadge-B4nmLus2.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudBadge-BnLiAHDN.js.map → CloudBadge-B4nmLus2.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudForgotPasswordView-BqDR_C7K.js → CloudForgotPasswordView-DOEV9hGr.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudForgotPasswordView-BqDR_C7K.js.map → CloudForgotPasswordView-DOEV9hGr.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudLayoutView-vTrrVUOY.js → CloudLayoutView-ShKH6rRV.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudLayoutView-vTrrVUOY.js.map → CloudLayoutView-ShKH6rRV.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudLoginView-T17euJly.js → CloudLoginView-C3Te42U9.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudLoginView-T17euJly.js.map → CloudLoginView-C3Te42U9.js.map} +1 -1
- comfyui_frontend_package/static/assets/CloudRunButtonWrapper-Cub7EB34.js +3 -0
- comfyui_frontend_package/static/assets/{CloudRunButtonWrapper-hQc4BNkX.js.map → CloudRunButtonWrapper-Cub7EB34.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudSignupView-vEDby5k3.js → CloudSignupView-X2oiL3ZR.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudSignupView-vEDby5k3.js.map → CloudSignupView-X2oiL3ZR.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudSubscriptionRedirectView-DPyO745g.js → CloudSubscriptionRedirectView-UjNv8emo.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudSubscriptionRedirectView-DPyO745g.js.map → CloudSubscriptionRedirectView-UjNv8emo.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudSurveyView-CBtTd9Ru.js → CloudSurveyView-IaiucCTP.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudSurveyView-CBtTd9Ru.js.map → CloudSurveyView-IaiucCTP.js.map} +1 -1
- comfyui_frontend_package/static/assets/ComfyQueueButton-BppnHbrl.js +1 -0
- comfyui_frontend_package/static/assets/{ComfyQueueButton-MZrp7wYJ.js → ComfyQueueButton-HjSIKZKO.js} +2 -2
- comfyui_frontend_package/static/assets/{ComfyQueueButton-MZrp7wYJ.js.map → ComfyQueueButton-HjSIKZKO.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ExtensionPanel-CrWVGUtg.js → ExtensionPanel-Bzb9QtKj.js} +2 -2
- comfyui_frontend_package/static/assets/{ExtensionPanel-CrWVGUtg.js.map → ExtensionPanel-Bzb9QtKj.js.map} +1 -1
- comfyui_frontend_package/static/assets/{GlobalToast-BiCmpIvO.js → GlobalToast-BSCvu6Hw.js} +2 -2
- comfyui_frontend_package/static/assets/{GlobalToast-BiCmpIvO.js.map → GlobalToast-BSCvu6Hw.js.map} +1 -1
- comfyui_frontend_package/static/assets/{GraphView-BCkpNGgz.js → GraphView-gYVCtm1V.js} +5 -5
- comfyui_frontend_package/static/assets/GraphView-gYVCtm1V.js.map +1 -0
- comfyui_frontend_package/static/assets/{KeybindingPanel-CAXL5TlV.js → KeybindingPanel-DF-bG4iO.js} +2 -2
- comfyui_frontend_package/static/assets/{KeybindingPanel-CAXL5TlV.js.map → KeybindingPanel-DF-bG4iO.js.map} +1 -1
- comfyui_frontend_package/static/assets/{LegacyCreditsPanel-6vR8koQy.js → LegacyCreditsPanel-D-CboO8k.js} +2 -2
- comfyui_frontend_package/static/assets/{LegacyCreditsPanel-6vR8koQy.js.map → LegacyCreditsPanel-D-CboO8k.js.map} +1 -1
- comfyui_frontend_package/static/assets/Load3D-c9UwgGoI.js +1 -0
- comfyui_frontend_package/static/assets/{Load3D-ei1BUF9O.js → Load3D-vYr8M3jJ.js} +2 -2
- comfyui_frontend_package/static/assets/{Load3D-ei1BUF9O.js.map → Load3D-vYr8M3jJ.js.map} +1 -1
- comfyui_frontend_package/static/assets/{PanelTemplate-BjN5XNg2.js → PanelTemplate-BJda9e5J.js} +2 -2
- comfyui_frontend_package/static/assets/{PanelTemplate-BjN5XNg2.js.map → PanelTemplate-BJda9e5J.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ServerConfigPanel-CxovH9Qk.js → ServerConfigPanel-VsC6xlZJ.js} +2 -2
- comfyui_frontend_package/static/assets/{ServerConfigPanel-CxovH9Qk.js.map → ServerConfigPanel-VsC6xlZJ.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscribeButton-CTOQRkfg.js → SubscribeButton-DZBycfCA.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscribeButton-CTOQRkfg.js.map → SubscribeButton-DZBycfCA.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscribeToRun-DnXzV8y0.js → SubscribeToRun-4YolxBOL.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscribeToRun-DnXzV8y0.js.map → SubscribeToRun-4YolxBOL.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscriptionPanel-D9uv7z8f.js → SubscriptionPanel-B6txX4Vm.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscriptionPanel-D9uv7z8f.js.map → SubscriptionPanel-B6txX4Vm.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscriptionRequiredDialogContent--VmT16oc.js → SubscriptionRequiredDialogContent-COEF2VQ_.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscriptionRequiredDialogContent--VmT16oc.js.map → SubscriptionRequiredDialogContent-COEF2VQ_.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserCheckView-spD3LyMu.js → UserCheckView-x-fkcYzc.js} +2 -2
- comfyui_frontend_package/static/assets/{UserCheckView-spD3LyMu.js.map → UserCheckView-x-fkcYzc.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserPanel-Su6NtJ5q.js → UserPanel-7N9QknQj.js} +2 -2
- comfyui_frontend_package/static/assets/{UserPanel-Su6NtJ5q.js.map → UserPanel-7N9QknQj.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserSelectView-C5LBOPcv.js → UserSelectView-BYjOkfSa.js} +2 -2
- comfyui_frontend_package/static/assets/{UserSelectView-C5LBOPcv.js.map → UserSelectView-BYjOkfSa.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ValueControlPopover-BdlDzT8l.js → ValueControlPopover-BPAa35QG.js} +2 -2
- comfyui_frontend_package/static/assets/{ValueControlPopover-BdlDzT8l.js.map → ValueControlPopover-BPAa35QG.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetAudioUI-BDZxDx_r.js → WidgetAudioUI-Dw-r3Ews.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetAudioUI-BDZxDx_r.js.map → WidgetAudioUI-Dw-r3Ews.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetImageCrop-CYRW7t2Q.js → WidgetImageCrop-kERy9g5I.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetImageCrop-CYRW7t2Q.js.map → WidgetImageCrop-kERy9g5I.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetInputNumber-BOKO36G3.js → WidgetInputNumber-BaClCNAC.js} +1 -1
- comfyui_frontend_package/static/assets/WidgetInputNumber-DU_D0Fzy.js +3 -0
- comfyui_frontend_package/static/assets/WidgetInputNumber-DU_D0Fzy.js.map +1 -0
- comfyui_frontend_package/static/assets/{WidgetLegacy-Bslv9wZZ.js → WidgetLegacy-B4nipUM9.js} +1 -1
- comfyui_frontend_package/static/assets/{WidgetRecordAudio-Bzy8PIzN.js → WidgetRecordAudio-Nk8dH238.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetRecordAudio-Bzy8PIzN.js.map → WidgetRecordAudio-Nk8dH238.js.map} +1 -1
- comfyui_frontend_package/static/assets/WidgetSelect-DzZPpO_-.js +1 -0
- comfyui_frontend_package/static/assets/{WidgetSelect-zgrFVzHH.js → WidgetSelect-nSQrk_hd.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetSelect-zgrFVzHH.js.map → WidgetSelect-nSQrk_hd.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetWithControl-Dh2FWOiA.js → WidgetWithControl-Da6zUB5e.js} +3 -3
- comfyui_frontend_package/static/assets/{WidgetWithControl-Dh2FWOiA.js.map → WidgetWithControl-Da6zUB5e.js.map} +1 -1
- comfyui_frontend_package/static/assets/{api-CUAc7rDA.js → api-Dwq2LQIW.js} +4 -4
- comfyui_frontend_package/static/assets/api-Dwq2LQIW.js.map +1 -0
- comfyui_frontend_package/static/assets/{audioService-DvndbCi2.js → audioService-DvVaKhuU.js} +2 -2
- comfyui_frontend_package/static/assets/{audioService-DvndbCi2.js.map → audioService-DvVaKhuU.js.map} +1 -1
- comfyui_frontend_package/static/assets/{audioUtils-DpjpcKbH.js → audioUtils-DD4rUYVZ.js} +2 -2
- comfyui_frontend_package/static/assets/{audioUtils-DpjpcKbH.js.map → audioUtils-DD4rUYVZ.js.map} +1 -1
- comfyui_frontend_package/static/assets/{auth-B8ZZ0KKQ.js → auth-B9axG-yZ.js} +2 -2
- comfyui_frontend_package/static/assets/{auth-B8ZZ0KKQ.js.map → auth-B9axG-yZ.js.map} +1 -1
- comfyui_frontend_package/static/assets/auth-D74DTev8.js +1 -0
- comfyui_frontend_package/static/assets/{cloudBadges-C1a7fBky.js → cloudBadges-D5mGJbRy.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudBadges-C1a7fBky.js.map → cloudBadges-D5mGJbRy.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudFeedbackTopbarButton-DR0T8sWG.js → cloudFeedbackTopbarButton-RZUssOmb.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudFeedbackTopbarButton-DR0T8sWG.js.map → cloudFeedbackTopbarButton-RZUssOmb.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudRemoteConfig-DhMjC5TB.js → cloudRemoteConfig-F9J0iGyF.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudRemoteConfig-DhMjC5TB.js.map → cloudRemoteConfig-F9J0iGyF.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudSessionCookie-Duxk6ux1.js → cloudSessionCookie-MEORlqtg.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudSessionCookie-Duxk6ux1.js.map → cloudSessionCookie-MEORlqtg.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudSubscription-B8l6B9Nx.js → cloudSubscription-CuWNXKVx.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudSubscription-B8l6B9Nx.js.map → cloudSubscription-CuWNXKVx.js.map} +1 -1
- comfyui_frontend_package/static/assets/{core-DBfeqMDR.js → core-IYu8XAIx.js} +4 -4
- comfyui_frontend_package/static/assets/{core-DBfeqMDR.js.map → core-IYu8XAIx.js.map} +1 -1
- comfyui_frontend_package/static/assets/{dialogService-BZ1FmjZL.js → dialogService-YG0RH337.js} +9 -9
- comfyui_frontend_package/static/assets/{dialogService-BZ1FmjZL.js.map → dialogService-YG0RH337.js.map} +1 -1
- comfyui_frontend_package/static/assets/firebaseAuthStore-DnNaPbuZ.js +1 -0
- comfyui_frontend_package/static/assets/{graphHasMissingNodes-C79Wi51S.js → graphHasMissingNodes-BhD1N6zI.js} +2 -2
- comfyui_frontend_package/static/assets/{graphHasMissingNodes-C79Wi51S.js.map → graphHasMissingNodes-BhD1N6zI.js.map} +1 -1
- comfyui_frontend_package/static/assets/{index-CGxJFSof.js → index-BMy3twho.js} +3 -3
- comfyui_frontend_package/static/assets/{index-CGxJFSof.js.map → index-BMy3twho.js.map} +1 -1
- comfyui_frontend_package/static/assets/{index-DNpOhRra.css → index-KMO9qFHH.css} +1 -1
- comfyui_frontend_package/static/assets/{keybindingService-B88NjeAU.js → keybindingService-CBLPjYHI.js} +2 -2
- comfyui_frontend_package/static/assets/{keybindingService-B88NjeAU.js.map → keybindingService-CBLPjYHI.js.map} +1 -1
- comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js → releaseStore-DDOxzkVb.js} +2 -2
- comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js.map → releaseStore-DDOxzkVb.js.map} +1 -1
- comfyui_frontend_package/static/assets/releaseStore-iVkqunL8.js +1 -0
- comfyui_frontend_package/static/assets/{subscriptionCheckoutUtil-B_OvUP2T.js → subscriptionCheckoutUtil-DswSOreM.js} +2 -2
- comfyui_frontend_package/static/assets/{subscriptionCheckoutUtil-B_OvUP2T.js.map → subscriptionCheckoutUtil-DswSOreM.js.map} +1 -1
- comfyui_frontend_package/static/assets/{useCurrentUser-BJcn2Vgo.js → useCurrentUser-NdaCJzIK.js} +1 -1
- comfyui_frontend_package/static/assets/{useErrorHandling-CI8_F4yx.js → useErrorHandling-Cfa5N_7c.js} +2 -2
- comfyui_frontend_package/static/assets/{useErrorHandling-CI8_F4yx.js.map → useErrorHandling-Cfa5N_7c.js.map} +1 -1
- comfyui_frontend_package/static/assets/{useSubscriptionDialog-Chxkdny5.js → useSubscriptionDialog-792qfEJ2.js} +3 -3
- comfyui_frontend_package/static/assets/{useSubscriptionDialog-Chxkdny5.js.map → useSubscriptionDialog-792qfEJ2.js.map} +1 -1
- comfyui_frontend_package/static/assets/useSubscriptionDialog-B-eGeK3j.js +1 -0
- comfyui_frontend_package/static/assets/{userStore-BkgQPjq6.js → userStore-BAS9m9W6.js} +2 -2
- comfyui_frontend_package/static/assets/{userStore-BkgQPjq6.js.map → userStore-BAS9m9W6.js.map} +1 -1
- comfyui_frontend_package/static/assets/vendor-three-BFcUNSs9.js.map +1 -1
- comfyui_frontend_package/static/index.html +1 -1
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/METADATA +1 -1
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/RECORD +126 -126
- comfyui_frontend_package/static/assets/AudioPreviewPlayer-BoEdyGI_.js +0 -1
- comfyui_frontend_package/static/assets/CloudRunButtonWrapper-hQc4BNkX.js +0 -3
- comfyui_frontend_package/static/assets/ComfyQueueButton-BbQnRThI.js +0 -1
- comfyui_frontend_package/static/assets/GraphView-BCkpNGgz.js.map +0 -1
- comfyui_frontend_package/static/assets/Load3D-DHBmC_AU.js +0 -1
- comfyui_frontend_package/static/assets/WidgetInputNumber-DGKypM5j.js +0 -3
- comfyui_frontend_package/static/assets/WidgetInputNumber-DGKypM5j.js.map +0 -1
- comfyui_frontend_package/static/assets/WidgetSelect-DsJGH12l.js +0 -1
- comfyui_frontend_package/static/assets/api-CUAc7rDA.js.map +0 -1
- comfyui_frontend_package/static/assets/auth-D3RiiqZ8.js +0 -1
- comfyui_frontend_package/static/assets/firebaseAuthStore-CZgxeMyf.js +0 -1
- comfyui_frontend_package/static/assets/releaseStore-CubqSv5t.js +0 -1
- comfyui_frontend_package/static/assets/useSubscriptionDialog-BzMzio2H.js +0 -1
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/WHEEL +0 -0
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var T=Object.defineProperty;var S=(l,e)=>T(l,"name",{value:e,configurable:!0});import{X as $,c as B,f as D,l as M}from"./vendor-primevue-DcMRXJN3.js";import{$o as m,Ba as s,Do as h,Ha as A,Jo as c,Ka as F,Pa as _,Ua as o,Va as y,Xo as R,Ya as P,do as t,po as b,qa as g,za as p}from"./vendor-other-DlQF6V2E.js";import{p as U}from"./vendor-vue-D9IUuwPJ.js";import{Bt as E,Lt as V,zt as O}from"./api-
|
|
1
|
+
var T=Object.defineProperty;var S=(l,e)=>T(l,"name",{value:e,configurable:!0});import{X as $,c as B,f as D,l as M}from"./vendor-primevue-DcMRXJN3.js";import{$o as m,Ba as s,Do as h,Ha as A,Jo as c,Ka as F,Pa as _,Ua as o,Va as y,Xo as R,Ya as P,do as t,po as b,qa as g,za as p}from"./vendor-other-DlQF6V2E.js";import{p as U}from"./vendor-vue-D9IUuwPJ.js";import{Bt as E,Lt as V,zt as O}from"./api-Dwq2LQIW.js";import"./colorUtil-CzxntCbX.js";import{O as I,a as x,k as z,n as w,t as L,u as C}from"./PanelTemplate-BJda9e5J.js";var H={class:"grid grid-cols-2 gap-2"},X={class:"font-medium"},j=P({__name:"DeviceInfo",props:{device:{}},setup(l){const e=l,f=[{field:"name",header:"Name"},{field:"type",header:"Type"},{field:"vram_total",header:"VRAM Total"},{field:"vram_free",header:"VRAM Free"},{field:"torch_vram_total",header:"Torch VRAM Total"},{field:"torch_vram_free",header:"Torch VRAM Free"}],r=S((n,a)=>["vram_total","vram_free","torch_vram_total","torch_vram_free"].includes(a)?C(n):n,"formatValue");return(n,a)=>(t(),o("div",H,[(t(),o(_,null,b(f,i=>(t(),o(_,{key:i.field},[s("div",X,m(i.header),1),s("div",null,m(r(e.device[i.field],i.field)),1)],64))),64))]))}}),k=j,q={class:"system-stats"},J={class:"mb-6"},K={class:"mb-4 text-2xl font-semibold"},Y={class:"grid grid-cols-2 gap-2"},G={class:"font-medium"},Q={class:"mb-4 text-2xl font-semibold"},W=P({__name:"SystemStatsPanel",props:{stats:{}},setup(l){const e=l,f=p(()=>({...e.stats.system,argv:e.stats.system.argv.join(" ")})),r=p(()=>e.stats.devices.length>0),n=[{field:"os",header:"OS"},{field:"python_version",header:"Python Version"},{field:"embedded_python",header:"Embedded Python"},{field:"pytorch_version",header:"Pytorch Version"},{field:"argv",header:"Arguments"},{field:"ram_total",header:"RAM Total",formatNumber:C},{field:"ram_free",header:"RAM Free",formatNumber:C}],a=[{field:"cloud_version",header:"Cloud Version"},{field:"comfyui_version",header:"ComfyUI Version",format:x},{field:"comfyui_frontend_version",header:"Frontend Version",format:x},{field:"workflow_templates_version",header:"Templates Version"}],i=p(()=>V?a:n),N=S(d=>{const v=f.value[d.field];return d.formatNumber&&typeof v=="number"?d.formatNumber(v):d.format&&typeof v=="string"?d.format(v):v},"getDisplayValue");return(d,v)=>(t(),o("div",q,[s("div",J,[s("h2",K,m(d.$t("g.systemInfo")),1),s("div",Y,[(t(!0),o(_,null,b(i.value,u=>(t(),o(_,{key:u.field},[s("div",G,m(u.header),1),s("div",null,m(N(u)),1)],64))),128))])]),r.value?(t(),o(_,{key:0},[g(c($)),s("div",null,[s("h2",Q,m(d.$t("g.devices")),1),e.stats.devices.length>1?(t(),y(c(M),{key:0},{default:h(()=>[(t(!0),o(_,null,b(e.stats.devices,u=>(t(),y(c(D),{key:u.index,header:u.name,value:u.index},{default:h(()=>[g(k,{device:u},null,8,["device"])]),_:2},1032,["header","value"]))),128))]),_:1})):(t(),y(k,{key:1,device:e.stats.devices[0]},null,8,["device"]))])],64)):A("",!0)]))}}),Z=W;const ee=U("aboutPanel",()=>{const l="1.38.6",e=w(),f=I(),{staticUrls:r}=z(),n=p(()=>f?.systemStats?.system?.comfyui_version??""),a=p(()=>[{label:`ComfyUI ${E()?"v"+O().getComfyUIVersion():x(n.value)}`,url:V?r.comfyOrg:r.github,icon:V?"pi pi-cloud":"pi pi-github"},{label:`ComfyUI_frontend v${l}`,url:r.githubFrontend,icon:"pi pi-github"},{label:"Discord",url:r.discord,icon:"pi pi-discord"},{label:"ComfyOrg",url:r.comfyOrg,icon:"pi pi-globe"}]);return{badges:p(()=>[...a.value,...e.extensions.flatMap(i=>i.aboutPageBadges??[])])}});var te={class:"mb-2 text-2xl font-bold"},ae={class:"space-y-2"},se=["href","title"],re=P({__name:"AboutPanel",setup(l){const e=I(),f=ee();return(r,n)=>(t(),y(L,{value:"About",class:"about-container"},{default:h(()=>[s("h2",te,m(r.$t("g.about")),1),s("div",ae,[(t(!0),o(_,null,b(c(f).badges,a=>(t(),o("a",{key:a.url,href:a.url,target:"_blank",rel:"noopener noreferrer",class:"about-badge inline-flex items-center no-underline",title:a.url},[g(c(B),{class:"mr-2"},{icon:h(()=>[s("i",{class:R([a.icon,"mr-2 text-xl"])},null,2)]),default:h(()=>[F(" "+m(a.label),1)]),_:2},1024)],8,se))),128))]),g(c($)),c(e).systemStats?(t(),y(Z,{key:0,stats:c(e).systemStats},null,8,["stats"])):A("",!0)]),_:1}))}}),me=re;export{me as default};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=AboutPanel-
|
|
3
|
+
//# sourceMappingURL=AboutPanel-lkjGFasi.js.map
|
comfyui_frontend_package/static/assets/{AboutPanel-CHse5rOA.js.map → AboutPanel-lkjGFasi.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AboutPanel-CHse5rOA.js","names":[],"sources":["../../src/components/common/DeviceInfo.vue","../../src/components/common/DeviceInfo.vue","../../src/components/common/SystemStatsPanel.vue","../../src/components/common/SystemStatsPanel.vue","../../src/stores/aboutPanelStore.ts","../../src/components/dialog/content/setting/AboutPanel.vue","../../src/components/dialog/content/setting/AboutPanel.vue"],"sourcesContent":["<template>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in deviceColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>\n {{ formatValue(props.device[col.field], col.field) }}\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DeviceStats } from '@/schemas/apiSchema'\nimport { formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n device: DeviceStats\n}>()\n\nconst deviceColumns: { field: keyof DeviceStats; header: string }[] = [\n { field: 'name', header: 'Name' },\n { field: 'type', header: 'Type' },\n { field: 'vram_total', header: 'VRAM Total' },\n { field: 'vram_free', header: 'VRAM Free' },\n { field: 'torch_vram_total', header: 'Torch VRAM Total' },\n { field: 'torch_vram_free', header: 'Torch VRAM Free' }\n]\n\nconst formatValue = (value: any, field: string) => {\n if (\n ['vram_total', 'vram_free', 'torch_vram_total', 'torch_vram_free'].includes(\n field\n )\n ) {\n return formatSize(value)\n }\n return value\n}\n</script>\n","<template>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in deviceColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>\n {{ formatValue(props.device[col.field], col.field) }}\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DeviceStats } from '@/schemas/apiSchema'\nimport { formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n device: DeviceStats\n}>()\n\nconst deviceColumns: { field: keyof DeviceStats; header: string }[] = [\n { field: 'name', header: 'Name' },\n { field: 'type', header: 'Type' },\n { field: 'vram_total', header: 'VRAM Total' },\n { field: 'vram_free', header: 'VRAM Free' },\n { field: 'torch_vram_total', header: 'Torch VRAM Total' },\n { field: 'torch_vram_free', header: 'Torch VRAM Free' }\n]\n\nconst formatValue = (value: any, field: string) => {\n if (\n ['vram_total', 'vram_free', 'torch_vram_total', 'torch_vram_free'].includes(\n field\n )\n ) {\n return formatSize(value)\n }\n return value\n}\n</script>\n","<template>\n <div class=\"system-stats\">\n <div class=\"mb-6\">\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.systemInfo') }}\n </h2>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in systemColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>{{ getDisplayValue(col) }}</div>\n </template>\n </div>\n </div>\n\n <template v-if=\"hasDevices\">\n <Divider />\n\n <div>\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.devices') }}\n </h2>\n <TabView v-if=\"props.stats.devices.length > 1\">\n <TabPanel\n v-for=\"device in props.stats.devices\"\n :key=\"device.index\"\n :header=\"device.name\"\n :value=\"device.index\"\n >\n <DeviceInfo :device=\"device\" />\n </TabPanel>\n </TabView>\n <DeviceInfo v-else :device=\"props.stats.devices[0]\" />\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport TabPanel from 'primevue/tabpanel'\nimport TabView from 'primevue/tabview'\nimport { computed } from 'vue'\n\nimport DeviceInfo from '@/components/common/DeviceInfo.vue'\nimport { isCloud } from '@/platform/distribution/types'\nimport type { SystemStats } from '@/schemas/apiSchema'\nimport { formatCommitHash, formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n stats: SystemStats\n}>()\n\nconst systemInfo = computed(() => ({\n ...props.stats.system,\n argv: props.stats.system.argv.join(' ')\n}))\n\nconst hasDevices = computed(() => props.stats.devices.length > 0)\n\ntype SystemInfoKey = keyof SystemStats['system']\n\ntype ColumnDef = {\n field: SystemInfoKey\n header: string\n format?: (value: string) => string\n formatNumber?: (value: number) => string\n}\n\n/** Columns for local distribution */\nconst localColumns: ColumnDef[] = [\n { field: 'os', header: 'OS' },\n { field: 'python_version', header: 'Python Version' },\n { field: 'embedded_python', header: 'Embedded Python' },\n { field: 'pytorch_version', header: 'Pytorch Version' },\n { field: 'argv', header: 'Arguments' },\n { field: 'ram_total', header: 'RAM Total', formatNumber: formatSize },\n { field: 'ram_free', header: 'RAM Free', formatNumber: formatSize }\n]\n\n/** Columns for cloud distribution */\nconst cloudColumns: ColumnDef[] = [\n { field: 'cloud_version', header: 'Cloud Version' },\n {\n field: 'comfyui_version',\n header: 'ComfyUI Version',\n format: formatCommitHash\n },\n {\n field: 'comfyui_frontend_version',\n header: 'Frontend Version',\n format: formatCommitHash\n },\n { field: 'workflow_templates_version', header: 'Templates Version' }\n]\n\nconst systemColumns = computed(() => (isCloud ? cloudColumns : localColumns))\n\nconst getDisplayValue = (column: ColumnDef) => {\n const value = systemInfo.value[column.field]\n if (column.formatNumber && typeof value === 'number') {\n return column.formatNumber(value)\n }\n if (column.format && typeof value === 'string') {\n return column.format(value)\n }\n return value\n}\n</script>\n","<template>\n <div class=\"system-stats\">\n <div class=\"mb-6\">\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.systemInfo') }}\n </h2>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in systemColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>{{ getDisplayValue(col) }}</div>\n </template>\n </div>\n </div>\n\n <template v-if=\"hasDevices\">\n <Divider />\n\n <div>\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.devices') }}\n </h2>\n <TabView v-if=\"props.stats.devices.length > 1\">\n <TabPanel\n v-for=\"device in props.stats.devices\"\n :key=\"device.index\"\n :header=\"device.name\"\n :value=\"device.index\"\n >\n <DeviceInfo :device=\"device\" />\n </TabPanel>\n </TabView>\n <DeviceInfo v-else :device=\"props.stats.devices[0]\" />\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport TabPanel from 'primevue/tabpanel'\nimport TabView from 'primevue/tabview'\nimport { computed } from 'vue'\n\nimport DeviceInfo from '@/components/common/DeviceInfo.vue'\nimport { isCloud } from '@/platform/distribution/types'\nimport type { SystemStats } from '@/schemas/apiSchema'\nimport { formatCommitHash, formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n stats: SystemStats\n}>()\n\nconst systemInfo = computed(() => ({\n ...props.stats.system,\n argv: props.stats.system.argv.join(' ')\n}))\n\nconst hasDevices = computed(() => props.stats.devices.length > 0)\n\ntype SystemInfoKey = keyof SystemStats['system']\n\ntype ColumnDef = {\n field: SystemInfoKey\n header: string\n format?: (value: string) => string\n formatNumber?: (value: number) => string\n}\n\n/** Columns for local distribution */\nconst localColumns: ColumnDef[] = [\n { field: 'os', header: 'OS' },\n { field: 'python_version', header: 'Python Version' },\n { field: 'embedded_python', header: 'Embedded Python' },\n { field: 'pytorch_version', header: 'Pytorch Version' },\n { field: 'argv', header: 'Arguments' },\n { field: 'ram_total', header: 'RAM Total', formatNumber: formatSize },\n { field: 'ram_free', header: 'RAM Free', formatNumber: formatSize }\n]\n\n/** Columns for cloud distribution */\nconst cloudColumns: ColumnDef[] = [\n { field: 'cloud_version', header: 'Cloud Version' },\n {\n field: 'comfyui_version',\n header: 'ComfyUI Version',\n format: formatCommitHash\n },\n {\n field: 'comfyui_frontend_version',\n header: 'Frontend Version',\n format: formatCommitHash\n },\n { field: 'workflow_templates_version', header: 'Templates Version' }\n]\n\nconst systemColumns = computed(() => (isCloud ? cloudColumns : localColumns))\n\nconst getDisplayValue = (column: ColumnDef) => {\n const value = systemInfo.value[column.field]\n if (column.formatNumber && typeof value === 'number') {\n return column.formatNumber(value)\n }\n if (column.format && typeof value === 'string') {\n return column.format(value)\n }\n return value\n}\n</script>\n","import { defineStore } from 'pinia'\nimport { computed } from 'vue'\n\nimport { useExternalLink } from '@/composables/useExternalLink'\nimport { isCloud } from '@/platform/distribution/types'\nimport type { AboutPageBadge } from '@/types/comfy'\nimport { electronAPI, isElectron } from '@/utils/envUtil'\nimport { formatCommitHash } from '@/utils/formatUtil'\n\nimport { useExtensionStore } from './extensionStore'\nimport { useSystemStatsStore } from './systemStatsStore'\n\nexport const useAboutPanelStore = defineStore('aboutPanel', () => {\n const frontendVersion = __COMFYUI_FRONTEND_VERSION__\n const extensionStore = useExtensionStore()\n const systemStatsStore = useSystemStatsStore()\n const { staticUrls } = useExternalLink()\n const coreVersion = computed(\n () => systemStatsStore?.systemStats?.system?.comfyui_version ?? ''\n )\n\n const coreBadges = computed<AboutPageBadge[]>(() => [\n // In electron, the ComfyUI is packaged without the git repo,\n // so the python server's API doesn't have the version info.\n {\n label: `ComfyUI ${\n isElectron()\n ? 'v' + electronAPI().getComfyUIVersion()\n : formatCommitHash(coreVersion.value)\n }`,\n url: isCloud ? staticUrls.comfyOrg : staticUrls.github,\n icon: isCloud ? 'pi pi-cloud' : 'pi pi-github'\n },\n {\n label: `ComfyUI_frontend v${frontendVersion}`,\n url: staticUrls.githubFrontend,\n icon: 'pi pi-github'\n },\n {\n label: 'Discord',\n url: staticUrls.discord,\n icon: 'pi pi-discord'\n },\n { label: 'ComfyOrg', url: staticUrls.comfyOrg, icon: 'pi pi-globe' }\n ])\n\n const allBadges = computed<AboutPageBadge[]>(() => [\n ...coreBadges.value,\n ...extensionStore.extensions.flatMap((e) => e.aboutPageBadges ?? [])\n ])\n\n return {\n badges: allBadges\n }\n})\n","<template>\n <PanelTemplate value=\"About\" class=\"about-container\">\n <h2 class=\"mb-2 text-2xl font-bold\">\n {{ $t('g.about') }}\n </h2>\n <div class=\"space-y-2\">\n <a\n v-for=\"badge in aboutPanelStore.badges\"\n :key=\"badge.url\"\n :href=\"badge.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"about-badge inline-flex items-center no-underline\"\n :title=\"badge.url\"\n >\n <Tag class=\"mr-2\">\n <template #icon>\n <i :class=\"[badge.icon, 'mr-2 text-xl']\" />\n </template>\n {{ badge.label }}\n </Tag>\n </a>\n </div>\n\n <Divider />\n\n <SystemStatsPanel\n v-if=\"systemStatsStore.systemStats\"\n :stats=\"systemStatsStore.systemStats\"\n />\n </PanelTemplate>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport Tag from 'primevue/tag'\n\nimport SystemStatsPanel from '@/components/common/SystemStatsPanel.vue'\nimport { useAboutPanelStore } from '@/stores/aboutPanelStore'\nimport { useSystemStatsStore } from '@/stores/systemStatsStore'\n\nimport PanelTemplate from './PanelTemplate.vue'\n\nconst systemStatsStore = useSystemStatsStore()\nconst aboutPanelStore = useAboutPanelStore()\n</script>\n","<template>\n <PanelTemplate value=\"About\" class=\"about-container\">\n <h2 class=\"mb-2 text-2xl font-bold\">\n {{ $t('g.about') }}\n </h2>\n <div class=\"space-y-2\">\n <a\n v-for=\"badge in aboutPanelStore.badges\"\n :key=\"badge.url\"\n :href=\"badge.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"about-badge inline-flex items-center no-underline\"\n :title=\"badge.url\"\n >\n <Tag class=\"mr-2\">\n <template #icon>\n <i :class=\"[badge.icon, 'mr-2 text-xl']\" />\n </template>\n {{ badge.label }}\n </Tag>\n </a>\n </div>\n\n <Divider />\n\n <SystemStatsPanel\n v-if=\"systemStatsStore.systemStats\"\n :stats=\"systemStatsStore.systemStats\"\n />\n </PanelTemplate>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport Tag from 'primevue/tag'\n\nimport SystemStatsPanel from '@/components/common/SystemStatsPanel.vue'\nimport { useAboutPanelStore } from '@/stores/aboutPanelStore'\nimport { useSystemStatsStore } from '@/stores/systemStatsStore'\n\nimport PanelTemplate from './PanelTemplate.vue'\n\nconst systemStatsStore = useSystemStatsStore()\nconst aboutPanelStore = useAboutPanelStore()\n</script>\n"],"mappings":"goBCiBA,MAAM,EAAQ,EAIR,EAAgE,CACpE,CAAE,MAAO,OAAQ,OAAQ,QACzB,CAAE,MAAO,OAAQ,OAAQ,QACzB,CAAE,MAAO,aAAc,OAAQ,cAC/B,CAAE,MAAO,YAAa,OAAQ,aAC9B,CAAE,MAAO,mBAAoB,OAAQ,oBACrC,CAAE,MAAO,kBAAmB,OAAQ,oBAGhC,EAAA,EAAA,CAAe,EAAY,IAE7B,CAAC,aAAc,YAAa,mBAAoB,mBAAmB,SACjE,CAAA,EAGK,EAAW,CAAA,EAEb,EARH,saEoBN,MAAM,EAAQ,EAIR,EAAa,EAAA,KAAgB,CACjC,GAAG,EAAM,MAAM,OACf,KAAM,EAAM,MAAM,OAAO,KAAK,KAAK,GAAA,GACpC,EAEK,EAAa,EAAA,IAAe,EAAM,MAAM,QAAQ,OAAS,CAAA,EAYzD,EAA4B,CAChC,CAAE,MAAO,KAAM,OAAQ,MACvB,CAAE,MAAO,iBAAkB,OAAQ,kBACnC,CAAE,MAAO,kBAAmB,OAAQ,mBACpC,CAAE,MAAO,kBAAmB,OAAQ,mBACpC,CAAE,MAAO,OAAQ,OAAQ,aACzB,CAAE,MAAO,YAAa,OAAQ,YAAa,aAAc,GACzD,CAAE,MAAO,WAAY,OAAQ,WAAY,aAAc,IAInD,EAA4B,CAChC,CAAE,MAAO,gBAAiB,OAAQ,iBAClC,CACE,MAAO,kBACP,OAAQ,kBACR,OAAQ,GAEV,CACE,MAAO,2BACP,OAAQ,mBACR,OAAQ,GAEV,CAAE,MAAO,6BAA8B,OAAQ,sBAG3C,EAAgB,EAAA,IAAgB,EAAU,EAAe,CAAA,EAEzD,EAAA,EAAmB,GAAsB,CAC7C,MAAM,EAAQ,EAAW,MAAM,EAAO,KAAA,EACtC,OAAI,EAAO,cAAgB,OAAO,GAAU,SACnC,EAAO,aAAa,CAAA,EAEzB,EAAO,QAAU,OAAO,GAAU,SAC7B,EAAO,OAAO,CAAA,EAEhB,GARH,uoBCvFN,MAAa,GAAqB,EAAY,aAAA,IAAoB,CAChE,MAAM,EAAA,SACA,EAAiB,EAAA,EACjB,EAAmB,EAAA,EACnB,CAAE,WAAA,CAAA,EAAe,EAAA,EACjB,EAAc,EAAA,IACZ,GAAkB,aAAa,QAAQ,iBAAmB,EAAA,EAG5D,EAAa,EAAA,IAAiC,CAGlD,CACE,MAAO,WACL,EAAA,EACI,IAAM,EAAA,EAAc,kBAAA,EACpB,EAAiB,EAAY,KAAA,CAAM,GAEzC,IAAK,EAAU,EAAW,SAAW,EAAW,OAChD,KAAM,EAAU,cAAgB,gBAElC,CACE,MAAO,qBAAqB,CAAA,GAC5B,IAAK,EAAW,eAChB,KAAM,gBAER,CACE,MAAO,UACP,IAAK,EAAW,QAChB,KAAM,iBAER,CAAE,MAAO,WAAY,IAAK,EAAW,SAAU,KAAM,eACtD,EAOD,MAAO,CACL,OANgB,EAAA,IAAiC,CACjD,GAAG,EAAW,MACd,GAAG,EAAe,WAAW,QAAS,GAAM,EAAE,iBAAmB,CAAA,CAAE,CAAC,CACrE,CAAC,2HENJ,MAAM,EAAmB,EAAA,EACnB,EAAkB,GAAA"}
|
|
1
|
+
{"version":3,"file":"AboutPanel-lkjGFasi.js","names":[],"sources":["../../src/components/common/DeviceInfo.vue","../../src/components/common/DeviceInfo.vue","../../src/components/common/SystemStatsPanel.vue","../../src/components/common/SystemStatsPanel.vue","../../src/stores/aboutPanelStore.ts","../../src/components/dialog/content/setting/AboutPanel.vue","../../src/components/dialog/content/setting/AboutPanel.vue"],"sourcesContent":["<template>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in deviceColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>\n {{ formatValue(props.device[col.field], col.field) }}\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DeviceStats } from '@/schemas/apiSchema'\nimport { formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n device: DeviceStats\n}>()\n\nconst deviceColumns: { field: keyof DeviceStats; header: string }[] = [\n { field: 'name', header: 'Name' },\n { field: 'type', header: 'Type' },\n { field: 'vram_total', header: 'VRAM Total' },\n { field: 'vram_free', header: 'VRAM Free' },\n { field: 'torch_vram_total', header: 'Torch VRAM Total' },\n { field: 'torch_vram_free', header: 'Torch VRAM Free' }\n]\n\nconst formatValue = (value: any, field: string) => {\n if (\n ['vram_total', 'vram_free', 'torch_vram_total', 'torch_vram_free'].includes(\n field\n )\n ) {\n return formatSize(value)\n }\n return value\n}\n</script>\n","<template>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in deviceColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>\n {{ formatValue(props.device[col.field], col.field) }}\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DeviceStats } from '@/schemas/apiSchema'\nimport { formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n device: DeviceStats\n}>()\n\nconst deviceColumns: { field: keyof DeviceStats; header: string }[] = [\n { field: 'name', header: 'Name' },\n { field: 'type', header: 'Type' },\n { field: 'vram_total', header: 'VRAM Total' },\n { field: 'vram_free', header: 'VRAM Free' },\n { field: 'torch_vram_total', header: 'Torch VRAM Total' },\n { field: 'torch_vram_free', header: 'Torch VRAM Free' }\n]\n\nconst formatValue = (value: any, field: string) => {\n if (\n ['vram_total', 'vram_free', 'torch_vram_total', 'torch_vram_free'].includes(\n field\n )\n ) {\n return formatSize(value)\n }\n return value\n}\n</script>\n","<template>\n <div class=\"system-stats\">\n <div class=\"mb-6\">\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.systemInfo') }}\n </h2>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in systemColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>{{ getDisplayValue(col) }}</div>\n </template>\n </div>\n </div>\n\n <template v-if=\"hasDevices\">\n <Divider />\n\n <div>\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.devices') }}\n </h2>\n <TabView v-if=\"props.stats.devices.length > 1\">\n <TabPanel\n v-for=\"device in props.stats.devices\"\n :key=\"device.index\"\n :header=\"device.name\"\n :value=\"device.index\"\n >\n <DeviceInfo :device=\"device\" />\n </TabPanel>\n </TabView>\n <DeviceInfo v-else :device=\"props.stats.devices[0]\" />\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport TabPanel from 'primevue/tabpanel'\nimport TabView from 'primevue/tabview'\nimport { computed } from 'vue'\n\nimport DeviceInfo from '@/components/common/DeviceInfo.vue'\nimport { isCloud } from '@/platform/distribution/types'\nimport type { SystemStats } from '@/schemas/apiSchema'\nimport { formatCommitHash, formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n stats: SystemStats\n}>()\n\nconst systemInfo = computed(() => ({\n ...props.stats.system,\n argv: props.stats.system.argv.join(' ')\n}))\n\nconst hasDevices = computed(() => props.stats.devices.length > 0)\n\ntype SystemInfoKey = keyof SystemStats['system']\n\ntype ColumnDef = {\n field: SystemInfoKey\n header: string\n format?: (value: string) => string\n formatNumber?: (value: number) => string\n}\n\n/** Columns for local distribution */\nconst localColumns: ColumnDef[] = [\n { field: 'os', header: 'OS' },\n { field: 'python_version', header: 'Python Version' },\n { field: 'embedded_python', header: 'Embedded Python' },\n { field: 'pytorch_version', header: 'Pytorch Version' },\n { field: 'argv', header: 'Arguments' },\n { field: 'ram_total', header: 'RAM Total', formatNumber: formatSize },\n { field: 'ram_free', header: 'RAM Free', formatNumber: formatSize }\n]\n\n/** Columns for cloud distribution */\nconst cloudColumns: ColumnDef[] = [\n { field: 'cloud_version', header: 'Cloud Version' },\n {\n field: 'comfyui_version',\n header: 'ComfyUI Version',\n format: formatCommitHash\n },\n {\n field: 'comfyui_frontend_version',\n header: 'Frontend Version',\n format: formatCommitHash\n },\n { field: 'workflow_templates_version', header: 'Templates Version' }\n]\n\nconst systemColumns = computed(() => (isCloud ? cloudColumns : localColumns))\n\nconst getDisplayValue = (column: ColumnDef) => {\n const value = systemInfo.value[column.field]\n if (column.formatNumber && typeof value === 'number') {\n return column.formatNumber(value)\n }\n if (column.format && typeof value === 'string') {\n return column.format(value)\n }\n return value\n}\n</script>\n","<template>\n <div class=\"system-stats\">\n <div class=\"mb-6\">\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.systemInfo') }}\n </h2>\n <div class=\"grid grid-cols-2 gap-2\">\n <template v-for=\"col in systemColumns\" :key=\"col.field\">\n <div class=\"font-medium\">\n {{ col.header }}\n </div>\n <div>{{ getDisplayValue(col) }}</div>\n </template>\n </div>\n </div>\n\n <template v-if=\"hasDevices\">\n <Divider />\n\n <div>\n <h2 class=\"mb-4 text-2xl font-semibold\">\n {{ $t('g.devices') }}\n </h2>\n <TabView v-if=\"props.stats.devices.length > 1\">\n <TabPanel\n v-for=\"device in props.stats.devices\"\n :key=\"device.index\"\n :header=\"device.name\"\n :value=\"device.index\"\n >\n <DeviceInfo :device=\"device\" />\n </TabPanel>\n </TabView>\n <DeviceInfo v-else :device=\"props.stats.devices[0]\" />\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport TabPanel from 'primevue/tabpanel'\nimport TabView from 'primevue/tabview'\nimport { computed } from 'vue'\n\nimport DeviceInfo from '@/components/common/DeviceInfo.vue'\nimport { isCloud } from '@/platform/distribution/types'\nimport type { SystemStats } from '@/schemas/apiSchema'\nimport { formatCommitHash, formatSize } from '@/utils/formatUtil'\n\nconst props = defineProps<{\n stats: SystemStats\n}>()\n\nconst systemInfo = computed(() => ({\n ...props.stats.system,\n argv: props.stats.system.argv.join(' ')\n}))\n\nconst hasDevices = computed(() => props.stats.devices.length > 0)\n\ntype SystemInfoKey = keyof SystemStats['system']\n\ntype ColumnDef = {\n field: SystemInfoKey\n header: string\n format?: (value: string) => string\n formatNumber?: (value: number) => string\n}\n\n/** Columns for local distribution */\nconst localColumns: ColumnDef[] = [\n { field: 'os', header: 'OS' },\n { field: 'python_version', header: 'Python Version' },\n { field: 'embedded_python', header: 'Embedded Python' },\n { field: 'pytorch_version', header: 'Pytorch Version' },\n { field: 'argv', header: 'Arguments' },\n { field: 'ram_total', header: 'RAM Total', formatNumber: formatSize },\n { field: 'ram_free', header: 'RAM Free', formatNumber: formatSize }\n]\n\n/** Columns for cloud distribution */\nconst cloudColumns: ColumnDef[] = [\n { field: 'cloud_version', header: 'Cloud Version' },\n {\n field: 'comfyui_version',\n header: 'ComfyUI Version',\n format: formatCommitHash\n },\n {\n field: 'comfyui_frontend_version',\n header: 'Frontend Version',\n format: formatCommitHash\n },\n { field: 'workflow_templates_version', header: 'Templates Version' }\n]\n\nconst systemColumns = computed(() => (isCloud ? cloudColumns : localColumns))\n\nconst getDisplayValue = (column: ColumnDef) => {\n const value = systemInfo.value[column.field]\n if (column.formatNumber && typeof value === 'number') {\n return column.formatNumber(value)\n }\n if (column.format && typeof value === 'string') {\n return column.format(value)\n }\n return value\n}\n</script>\n","import { defineStore } from 'pinia'\nimport { computed } from 'vue'\n\nimport { useExternalLink } from '@/composables/useExternalLink'\nimport { isCloud } from '@/platform/distribution/types'\nimport type { AboutPageBadge } from '@/types/comfy'\nimport { electronAPI, isElectron } from '@/utils/envUtil'\nimport { formatCommitHash } from '@/utils/formatUtil'\n\nimport { useExtensionStore } from './extensionStore'\nimport { useSystemStatsStore } from './systemStatsStore'\n\nexport const useAboutPanelStore = defineStore('aboutPanel', () => {\n const frontendVersion = __COMFYUI_FRONTEND_VERSION__\n const extensionStore = useExtensionStore()\n const systemStatsStore = useSystemStatsStore()\n const { staticUrls } = useExternalLink()\n const coreVersion = computed(\n () => systemStatsStore?.systemStats?.system?.comfyui_version ?? ''\n )\n\n const coreBadges = computed<AboutPageBadge[]>(() => [\n // In electron, the ComfyUI is packaged without the git repo,\n // so the python server's API doesn't have the version info.\n {\n label: `ComfyUI ${\n isElectron()\n ? 'v' + electronAPI().getComfyUIVersion()\n : formatCommitHash(coreVersion.value)\n }`,\n url: isCloud ? staticUrls.comfyOrg : staticUrls.github,\n icon: isCloud ? 'pi pi-cloud' : 'pi pi-github'\n },\n {\n label: `ComfyUI_frontend v${frontendVersion}`,\n url: staticUrls.githubFrontend,\n icon: 'pi pi-github'\n },\n {\n label: 'Discord',\n url: staticUrls.discord,\n icon: 'pi pi-discord'\n },\n { label: 'ComfyOrg', url: staticUrls.comfyOrg, icon: 'pi pi-globe' }\n ])\n\n const allBadges = computed<AboutPageBadge[]>(() => [\n ...coreBadges.value,\n ...extensionStore.extensions.flatMap((e) => e.aboutPageBadges ?? [])\n ])\n\n return {\n badges: allBadges\n }\n})\n","<template>\n <PanelTemplate value=\"About\" class=\"about-container\">\n <h2 class=\"mb-2 text-2xl font-bold\">\n {{ $t('g.about') }}\n </h2>\n <div class=\"space-y-2\">\n <a\n v-for=\"badge in aboutPanelStore.badges\"\n :key=\"badge.url\"\n :href=\"badge.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"about-badge inline-flex items-center no-underline\"\n :title=\"badge.url\"\n >\n <Tag class=\"mr-2\">\n <template #icon>\n <i :class=\"[badge.icon, 'mr-2 text-xl']\" />\n </template>\n {{ badge.label }}\n </Tag>\n </a>\n </div>\n\n <Divider />\n\n <SystemStatsPanel\n v-if=\"systemStatsStore.systemStats\"\n :stats=\"systemStatsStore.systemStats\"\n />\n </PanelTemplate>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport Tag from 'primevue/tag'\n\nimport SystemStatsPanel from '@/components/common/SystemStatsPanel.vue'\nimport { useAboutPanelStore } from '@/stores/aboutPanelStore'\nimport { useSystemStatsStore } from '@/stores/systemStatsStore'\n\nimport PanelTemplate from './PanelTemplate.vue'\n\nconst systemStatsStore = useSystemStatsStore()\nconst aboutPanelStore = useAboutPanelStore()\n</script>\n","<template>\n <PanelTemplate value=\"About\" class=\"about-container\">\n <h2 class=\"mb-2 text-2xl font-bold\">\n {{ $t('g.about') }}\n </h2>\n <div class=\"space-y-2\">\n <a\n v-for=\"badge in aboutPanelStore.badges\"\n :key=\"badge.url\"\n :href=\"badge.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"about-badge inline-flex items-center no-underline\"\n :title=\"badge.url\"\n >\n <Tag class=\"mr-2\">\n <template #icon>\n <i :class=\"[badge.icon, 'mr-2 text-xl']\" />\n </template>\n {{ badge.label }}\n </Tag>\n </a>\n </div>\n\n <Divider />\n\n <SystemStatsPanel\n v-if=\"systemStatsStore.systemStats\"\n :stats=\"systemStatsStore.systemStats\"\n />\n </PanelTemplate>\n</template>\n\n<script setup lang=\"ts\">\nimport Divider from 'primevue/divider'\nimport Tag from 'primevue/tag'\n\nimport SystemStatsPanel from '@/components/common/SystemStatsPanel.vue'\nimport { useAboutPanelStore } from '@/stores/aboutPanelStore'\nimport { useSystemStatsStore } from '@/stores/systemStatsStore'\n\nimport PanelTemplate from './PanelTemplate.vue'\n\nconst systemStatsStore = useSystemStatsStore()\nconst aboutPanelStore = useAboutPanelStore()\n</script>\n"],"mappings":"goBCiBA,MAAM,EAAQ,EAIR,EAAgE,CACpE,CAAE,MAAO,OAAQ,OAAQ,QACzB,CAAE,MAAO,OAAQ,OAAQ,QACzB,CAAE,MAAO,aAAc,OAAQ,cAC/B,CAAE,MAAO,YAAa,OAAQ,aAC9B,CAAE,MAAO,mBAAoB,OAAQ,oBACrC,CAAE,MAAO,kBAAmB,OAAQ,oBAGhC,EAAA,EAAA,CAAe,EAAY,IAE7B,CAAC,aAAc,YAAa,mBAAoB,mBAAmB,SACjE,CAAA,EAGK,EAAW,CAAA,EAEb,EARH,saEoBN,MAAM,EAAQ,EAIR,EAAa,EAAA,KAAgB,CACjC,GAAG,EAAM,MAAM,OACf,KAAM,EAAM,MAAM,OAAO,KAAK,KAAK,GAAA,GACpC,EAEK,EAAa,EAAA,IAAe,EAAM,MAAM,QAAQ,OAAS,CAAA,EAYzD,EAA4B,CAChC,CAAE,MAAO,KAAM,OAAQ,MACvB,CAAE,MAAO,iBAAkB,OAAQ,kBACnC,CAAE,MAAO,kBAAmB,OAAQ,mBACpC,CAAE,MAAO,kBAAmB,OAAQ,mBACpC,CAAE,MAAO,OAAQ,OAAQ,aACzB,CAAE,MAAO,YAAa,OAAQ,YAAa,aAAc,GACzD,CAAE,MAAO,WAAY,OAAQ,WAAY,aAAc,IAInD,EAA4B,CAChC,CAAE,MAAO,gBAAiB,OAAQ,iBAClC,CACE,MAAO,kBACP,OAAQ,kBACR,OAAQ,GAEV,CACE,MAAO,2BACP,OAAQ,mBACR,OAAQ,GAEV,CAAE,MAAO,6BAA8B,OAAQ,sBAG3C,EAAgB,EAAA,IAAgB,EAAU,EAAe,CAAA,EAEzD,EAAA,EAAmB,GAAsB,CAC7C,MAAM,EAAQ,EAAW,MAAM,EAAO,KAAA,EACtC,OAAI,EAAO,cAAgB,OAAO,GAAU,SACnC,EAAO,aAAa,CAAA,EAEzB,EAAO,QAAU,OAAO,GAAU,SAC7B,EAAO,OAAO,CAAA,EAEhB,GARH,uoBCvFN,MAAa,GAAqB,EAAY,aAAA,IAAoB,CAChE,MAAM,EAAA,SACA,EAAiB,EAAA,EACjB,EAAmB,EAAA,EACnB,CAAE,WAAA,CAAA,EAAe,EAAA,EACjB,EAAc,EAAA,IACZ,GAAkB,aAAa,QAAQ,iBAAmB,EAAA,EAG5D,EAAa,EAAA,IAAiC,CAGlD,CACE,MAAO,WACL,EAAA,EACI,IAAM,EAAA,EAAc,kBAAA,EACpB,EAAiB,EAAY,KAAA,CAAM,GAEzC,IAAK,EAAU,EAAW,SAAW,EAAW,OAChD,KAAM,EAAU,cAAgB,gBAElC,CACE,MAAO,qBAAqB,CAAA,GAC5B,IAAK,EAAW,eAChB,KAAM,gBAER,CACE,MAAO,UACP,IAAK,EAAW,QAChB,KAAM,iBAER,CAAE,MAAO,WAAY,IAAK,EAAW,SAAU,KAAM,eACtD,EAOD,MAAO,CACL,OANgB,EAAA,IAAiC,CACjD,GAAG,EAAW,MACd,GAAG,EAAe,WAAW,QAAS,GAAM,EAAE,iBAAmB,CAAA,CAAE,CAAC,CACrE,CAAC,2HENJ,MAAM,EAAmB,EAAA,EACnB,EAAkB,GAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var X=Object.defineProperty;var t=(k,i)=>X(k,"name",{value:i,configurable:!0});import{J as G,S as K}from"./vendor-primevue-DcMRXJN3.js";import{$o as _,Ba as o,Do as Z,Ha as C,Jo as p,Qo as ee,Ua as l,Xo as ae,Ya as te,do as s,io as oe,lo as le,qa as A,wo as se,za as u,zo as n}from"./vendor-other-DlQF6V2E.js";import{n as ue}from"./vendor-vue-D9IUuwPJ.js";import{Y as re,r as ne}from"./api-
|
|
1
|
+
var X=Object.defineProperty;var t=(k,i)=>X(k,"name",{value:i,configurable:!0});import{J as G,S as K}from"./vendor-primevue-DcMRXJN3.js";import{$o as _,Ba as o,Do as Z,Ha as C,Jo as p,Qo as ee,Ua as l,Xo as ae,Ya as te,do as s,io as oe,lo as le,qa as A,wo as se,za as u,zo as n}from"./vendor-other-DlQF6V2E.js";import{n as ue}from"./vendor-vue-D9IUuwPJ.js";import{Y as re,r as ne}from"./api-Dwq2LQIW.js";import{t as z}from"./src-DTrob8OL.js";import{P as B,ut as ie}from"./dialogService-YG0RH337.js";import{t as de}from"./_plugin-vue_export-helper-PHE0iSCb.js";import{r as ce,t as N}from"./audioUtils-DD4rUYVZ.js";import{n as ve}from"./nodeFilterUtil-BYFD-MqA.js";var pe={class:"relative"},me={class:"relative flex shrink-0 items-center justify-start gap-2"},fe=["aria-label"],ge={key:0,class:"text-secondary icon-[lucide--play] size-4"},he={key:1,class:"text-secondary icon-[lucide--pause] size-4"},ye={class:"text-sm font-normal text-nowrap text-base-foreground"},be={class:"relative h-0.5 flex-1 rounded-full bg-interface-stroke"},_e=["value","aria-label"],ke={class:"relative flex shrink-0 items-center justify-start gap-2"},xe=["aria-label"],we={key:0,class:"text-secondary icon-[lucide--volume-2] size-4"},Ce={key:1,class:"text-secondary icon-[lucide--volume-1] size-4"},ze={key:2,class:"text-secondary icon-[lucide--volume-x] size-4"},Pe=["aria-label"],Oe={key:0,class:"w-48 px-4 py-2"},Ie={class:"mb-2 block text-xs text-base-foreground"},Ue=["onClick"],Ae={class:"text-base-foreground"},Be={key:0,class:"ml-auto icon-[lucide--check] size-4 text-base-foreground"},Ne=te({__name:"AudioPreviewPlayer",props:{hideWhenEmpty:{type:Boolean,default:!0},showOptionsButton:{type:Boolean},nodeId:{},audioUrl:{}},setup(k){const{t:i}=ue(),h=k,a=n(),P=n(),m=n(!1),d=n(!1),f=n(1),g=n(0),c=n(0),O=n(!1),y=n(1),I=u(()=>!c.value||c.value===0?0:g.value/c.value*100),S=u(()=>!d.value&&f.value>.5),T=u(()=>d.value&&f.value>0),b=u(()=>!h.nodeId||!B.canvas.graph?null:B.canvas.graph.getNodeById(h.nodeId)),R=u(()=>b.value?b.value.constructor?.comfyClass==="LoadAudio"&&!!h.nodeId:!1),$=u(()=>{const e=b.value;return!!e&&ve(e)}),U=u(()=>{const e=b.value;return e?re(e):null}),L=ie(),V=u(()=>{if(!$.value||!U.value)return"";const e=L.nodeOutputs[U.value];if(!e?.audio||e.audio.length===0)return"";const r=e.audio[0];return r.filename?ne.apiURL(ce(r.subfolder||"",r.filename,r.type||"output")):""}),j=u(()=>V.value||h.audioUrl||""),M=t(()=>{!a.value||!a.value.src||(m.value?a.value.pause():a.value.play(),m.value=!m.value)},"togglePlayPause"),E=t(()=>{a.value&&(d.value=!d.value,a.value.muted=d.value)},"toggleMute"),F=t(e=>{const r=e.target,v=parseFloat(r.value);if(a.value&&c.value>0){const w=v/100*c.value;a.value.currentTime=w,g.value=w}},"handleSeek"),D=t(()=>{a.value&&(c.value=a.value.duration)},"handleLoadedMetadata"),J=t(()=>{a.value&&(g.value=a.value.currentTime)},"handleTimeUpdate"),W=t(()=>{m.value=!1,g.value=0},"handleEnded"),Y=t(e=>{P.value?.toggle(e)},"toggleOptionsMenu"),x=t(e=>{y.value=e,a.value&&(a.value.playbackRate=e)},"setPlaybackSpeed"),q=t(e=>{f.value=(Array.isArray(e)?e[0]:e)/10,a.value&&(a.value.volume=f.value,f.value>0&&d.value&&(d.value=!1,a.value.muted=!1))},"handleVolumeChange"),H=u(()=>[{label:i("g.playbackSpeed"),items:[{label:i("g.halfSpeed"),onClick:t(()=>x(.5),"onClick"),selected:y.value===.5},{label:i("g.1x"),onClick:t(()=>x(1),"onClick"),selected:y.value===1},{label:i("g.2x"),onClick:t(()=>x(2),"onClick"),selected:y.value===2}]},{label:i("g.volume"),key:"volume"}]),Q=t(e=>{a.value&&(m.value=!1,a.value.pause(),a.value.src=e,a.value.load(),O.value=!!e)},"loadAudioFromUrl");return se(j,e=>{e&&oe(()=>{Q(e)})},{immediate:!0}),le(()=>{a.value&&(a.value.pause(),a.value.src="")}),(e,r)=>(s(),l("div",pe,[R.value?C("",!0):(s(),l("div",{key:0,class:ae(p(z)("bg-component-node-widget-background box-border flex gap-4 items-center justify-start relative rounded-lg w-full h-16 px-4 py-0",{hidden:e.hideWhenEmpty&&!O.value}))},[o("audio",{ref_key:"audioRef",ref:a,onLoadedmetadata:D,onTimeupdate:J,onEnded:W},null,544),o("div",me,[o("div",{role:"button",tabindex:0,"aria-label":e.$t("g.playPause"),class:"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered",onClick:M},[m.value?(s(),l("i",he)):(s(),l("i",ge))],8,fe),o("div",ye,_(p(N)(g.value))+" / "+_(p(N)(c.value)),1)]),o("div",be,[o("div",{class:"absolute top-0 left-0 h-full rounded-full bg-button-icon transition-all",style:ee({width:`${I.value}%`})},null,4),o("input",{type:"range",value:I.value,min:"0",max:"100",step:"0.1","aria-label":e.$t("g.audioProgress"),class:"absolute inset-0 w-full cursor-pointer opacity-0",onInput:F},null,40,_e)]),o("div",ke,[o("div",{role:"button",tabindex:0,"aria-label":e.$t("g.volume"),class:"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered",onClick:E},[S.value?(s(),l("i",we)):T.value?(s(),l("i",Ce)):(s(),l("i",ze))],8,xe),e.showOptionsButton?(s(),l("div",{key:0,role:"button",tabindex:0,"aria-label":e.$t("g.moreOptions"),class:"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered",onClick:Y},r[0]||(r[0]=[o("i",{class:"text-secondary icon-[lucide--more-vertical] size-4"},null,-1)]),8,Pe)):C("",!0)]),A(p(K),{ref_key:"optionsMenu",ref:P,model:H.value,popup:"",class:"audio-player-menu","pt:root:class":p(z)("bg-component-node-widget-background border-component-node-border"),"pt:submenu:class":p(z)("bg-component-node-widget-background")},{item:Z(({item:v})=>[v.key==="volume"?(s(),l("div",Oe,[o("label",Ie,_(v.label),1),A(p(G),{"model-value":f.value*10,min:0,max:10,step:1,class:"w-full","onUpdate:modelValue":q},null,8,["model-value"])])):(s(),l("div",{key:1,class:"flex cursor-pointer items-center px-4 py-2 text-xs hover:bg-white/10",onClick:t(w=>v.onClick?.(),"onClick")},[o("span",Ae,_(v.label),1),v.selected?(s(),l("i",Be)):C("",!0)],8,Ue))]),_:1},8,["model","pt:root:class","pt:submenu:class"])],2))]))}}),De=de(Ne,[["__scopeId","data-v-b2e1591f"]]);export{De as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=AudioPreviewPlayer-
|
|
3
|
+
//# sourceMappingURL=AudioPreviewPlayer-BxCSKPl9.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioPreviewPlayer-CAa8V66L.js","names":[],"sources":["../../src/renderer/extensions/vueNodes/widgets/components/audio/AudioPreviewPlayer.vue","../../src/renderer/extensions/vueNodes/widgets/components/audio/AudioPreviewPlayer.vue"],"sourcesContent":["<template>\n <div class=\"relative\">\n <div\n v-if=\"!hidden\"\n :class=\"\n cn(\n 'bg-component-node-widget-background box-border flex gap-4 items-center justify-start relative rounded-lg w-full h-16 px-4 py-0',\n { hidden: hideWhenEmpty && !hasAudio }\n )\n \"\n >\n <!-- Hidden audio element -->\n <audio\n ref=\"audioRef\"\n @loadedmetadata=\"handleLoadedMetadata\"\n @timeupdate=\"handleTimeUpdate\"\n @ended=\"handleEnded\"\n />\n\n <!-- Left Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Play/Pause Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.playPause')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"togglePlayPause\"\n >\n <i\n v-if=\"!isPlaying\"\n class=\"text-secondary icon-[lucide--play] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--pause] size-4\" />\n </div>\n\n <!-- Time Display -->\n <div class=\"text-sm font-normal text-nowrap text-base-foreground\">\n {{ formatTime(currentTime) }} / {{ formatTime(duration) }}\n </div>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"relative h-0.5 flex-1 rounded-full bg-interface-stroke\">\n <div\n class=\"absolute top-0 left-0 h-full rounded-full bg-button-icon transition-all\"\n :style=\"{ width: `${progressPercentage}%` }\"\n />\n <input\n type=\"range\"\n :value=\"progressPercentage\"\n min=\"0\"\n max=\"100\"\n step=\"0.1\"\n :aria-label=\"$t('g.audioProgress')\"\n class=\"absolute inset-0 w-full cursor-pointer opacity-0\"\n @input=\"handleSeek\"\n />\n </div>\n\n <!-- Right Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Volume Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.volume')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleMute\"\n >\n <i\n v-if=\"showVolumeTwo\"\n class=\"text-secondary icon-[lucide--volume-2] size-4\"\n />\n <i\n v-else-if=\"showVolumeOne\"\n class=\"text-secondary icon-[lucide--volume-1] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--volume-x] size-4\" />\n </div>\n\n <!-- Options Button -->\n <div\n v-if=\"showOptionsButton\"\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.moreOptions')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleOptionsMenu\"\n >\n <i class=\"text-secondary icon-[lucide--more-vertical] size-4\" />\n </div>\n </div>\n\n <!-- Options Menu -->\n <TieredMenu\n ref=\"optionsMenu\"\n :model=\"menuItems\"\n popup\n class=\"audio-player-menu\"\n :pt:root:class=\"\n cn('bg-component-node-widget-background border-component-node-border')\n \"\n :pt:submenu:class=\"cn('bg-component-node-widget-background')\"\n >\n <template #item=\"{ item }\">\n <div v-if=\"item.key === 'volume'\" class=\"w-48 px-4 py-2\">\n <label class=\"mb-2 block text-xs text-base-foreground\">{{\n item.label\n }}</label>\n <Slider\n :model-value=\"volume * 10\"\n :min=\"0\"\n :max=\"10\"\n :step=\"1\"\n class=\"w-full\"\n @update:model-value=\"handleVolumeChange\"\n />\n </div>\n <div\n v-else\n class=\"flex cursor-pointer items-center px-4 py-2 text-xs hover:bg-white/10\"\n @click=\"item.onClick?.()\"\n >\n <span class=\"text-base-foreground\">{{ item.label }}</span>\n <i\n v-if=\"item.selected\"\n class=\"ml-auto icon-[lucide--check] size-4 text-base-foreground\"\n />\n </div>\n </template>\n </TieredMenu>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Slider from 'primevue/slider'\nimport TieredMenu from 'primevue/tieredmenu'\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\nimport { useI18n } from 'vue-i18n'\n\nimport type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'\nimport { api } from '@/scripts/api'\nimport { app } from '@/scripts/app'\nimport { useNodeOutputStore } from '@/stores/imagePreviewStore'\nimport { getLocatorIdFromNodeData } from '@/utils/graphTraversalUtil'\nimport { isOutputNode } from '@/utils/nodeFilterUtil'\nimport { cn } from '@/utils/tailwindUtil'\n\nimport { formatTime, getResourceURL } from '../../utils/audioUtils'\n\nconst { t } = useI18n()\n\nconst props = withDefaults(\n defineProps<{\n hideWhenEmpty?: boolean\n showOptionsButton?: boolean\n nodeId?: string\n audioUrl?: string\n }>(),\n {\n hideWhenEmpty: true\n }\n)\n\n// Refs\nconst audioRef = ref<HTMLAudioElement>()\nconst optionsMenu = ref()\nconst isPlaying = ref(false)\nconst isMuted = ref(false)\nconst volume = ref(1)\nconst currentTime = ref(0)\nconst duration = ref(0)\nconst hasAudio = ref(false)\nconst playbackRate = ref(1)\n\n// Computed\nconst progressPercentage = computed(() => {\n if (!duration.value || duration.value === 0) return 0\n return (currentTime.value / duration.value) * 100\n})\n\nconst showVolumeTwo = computed(() => !isMuted.value && volume.value > 0.5)\nconst showVolumeOne = computed(() => isMuted.value && volume.value > 0)\n\nconst litegraphNode = computed(() => {\n if (!props.nodeId || !app.canvas.graph) return null\n return app.canvas.graph.getNodeById(props.nodeId) as LGraphNode | null\n})\n\nconst hidden = computed(() => {\n if (!litegraphNode.value) return false\n // dont show if its a LoadAudio and we have nodeId\n const isLoadAudio =\n litegraphNode.value.constructor?.comfyClass === 'LoadAudio'\n return isLoadAudio && !!props.nodeId\n})\n\n// Check if this is an output node\nconst isOutputNodeRef = computed(() => {\n const node = litegraphNode.value\n return !!node && isOutputNode(node)\n})\n\nconst nodeLocatorId = computed(() => {\n const node = litegraphNode.value\n if (!node) return null\n return getLocatorIdFromNodeData(node)\n})\n\nconst nodeOutputStore = useNodeOutputStore()\n\n// Computed audio URL from node output (for output nodes)\nconst audioUrlFromOutput = computed(() => {\n if (!isOutputNodeRef.value || !nodeLocatorId.value) return ''\n\n const nodeOutput = nodeOutputStore.nodeOutputs[nodeLocatorId.value]\n if (!nodeOutput?.audio || nodeOutput.audio.length === 0) return ''\n\n const audio = nodeOutput.audio[0]\n if (!audio.filename) return ''\n\n return api.apiURL(\n getResourceURL(\n audio.subfolder || '',\n audio.filename,\n audio.type || 'output'\n )\n )\n})\n\n// Combined audio URL (output takes precedence for output nodes)\nconst finalAudioUrl = computed(() => {\n return audioUrlFromOutput.value || props.audioUrl || ''\n})\n\n// Playback controls\nconst togglePlayPause = () => {\n if (!audioRef.value || !audioRef.value.src) {\n return\n }\n\n if (isPlaying.value) {\n audioRef.value.pause()\n } else {\n void audioRef.value.play()\n }\n isPlaying.value = !isPlaying.value\n}\n\nconst toggleMute = () => {\n if (audioRef.value) {\n isMuted.value = !isMuted.value\n audioRef.value.muted = isMuted.value\n }\n}\n\nconst handleSeek = (event: Event) => {\n const target = event.target as HTMLInputElement\n const value = parseFloat(target.value)\n if (audioRef.value && duration.value > 0) {\n const newTime = (value / 100) * duration.value\n audioRef.value.currentTime = newTime\n currentTime.value = newTime\n }\n}\n\n// Audio events\nconst handleLoadedMetadata = () => {\n if (audioRef.value) {\n duration.value = audioRef.value.duration\n }\n}\n\nconst handleTimeUpdate = () => {\n if (audioRef.value) {\n currentTime.value = audioRef.value.currentTime\n }\n}\n\nconst handleEnded = () => {\n isPlaying.value = false\n currentTime.value = 0\n}\n\n// Options menu\nconst toggleOptionsMenu = (event: Event) => {\n optionsMenu.value?.toggle(event)\n}\n\nconst setPlaybackSpeed = (speed: number) => {\n playbackRate.value = speed\n if (audioRef.value) {\n audioRef.value.playbackRate = speed\n }\n}\n\nconst handleVolumeChange = (value: number | number[]) => {\n const numValue = Array.isArray(value) ? value[0] : value\n volume.value = numValue / 10\n if (audioRef.value) {\n audioRef.value.volume = volume.value\n if (volume.value > 0 && isMuted.value) {\n isMuted.value = false\n audioRef.value.muted = false\n }\n }\n}\n\nconst menuItems = computed(() => [\n {\n label: t('g.playbackSpeed'),\n items: [\n {\n label: t('g.halfSpeed'),\n onClick: () => setPlaybackSpeed(0.5),\n selected: playbackRate.value === 0.5\n },\n {\n label: t('g.1x'),\n onClick: () => setPlaybackSpeed(1),\n selected: playbackRate.value === 1\n },\n {\n label: t('g.2x'),\n onClick: () => setPlaybackSpeed(2),\n selected: playbackRate.value === 2\n }\n ]\n },\n {\n label: t('g.volume'),\n key: 'volume'\n }\n])\n\n// Load audio from URL\nconst loadAudioFromUrl = (url: string) => {\n if (!audioRef.value) return\n isPlaying.value = false\n audioRef.value.pause()\n audioRef.value.src = url\n void audioRef.value.load()\n hasAudio.value = !!url\n}\n\n// Watch for finalAudioUrl changes\nwatch(\n finalAudioUrl,\n (newUrl) => {\n if (newUrl) {\n void nextTick(() => {\n loadAudioFromUrl(newUrl)\n })\n }\n },\n { immediate: true }\n)\n\n// Cleanup\nonUnmounted(() => {\n if (audioRef.value) {\n audioRef.value.pause()\n audioRef.value.src = ''\n }\n})\n</script>\n\n<style scoped>\n.audio-player-menu {\n --p-tieredmenu-item-focus-background: rgb(255 255 255 / 0.1);\n --p-tieredmenu-item-active-background: rgb(255 255 255 / 0.1);\n}\n</style>\n","<template>\n <div class=\"relative\">\n <div\n v-if=\"!hidden\"\n :class=\"\n cn(\n 'bg-component-node-widget-background box-border flex gap-4 items-center justify-start relative rounded-lg w-full h-16 px-4 py-0',\n { hidden: hideWhenEmpty && !hasAudio }\n )\n \"\n >\n <!-- Hidden audio element -->\n <audio\n ref=\"audioRef\"\n @loadedmetadata=\"handleLoadedMetadata\"\n @timeupdate=\"handleTimeUpdate\"\n @ended=\"handleEnded\"\n />\n\n <!-- Left Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Play/Pause Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.playPause')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"togglePlayPause\"\n >\n <i\n v-if=\"!isPlaying\"\n class=\"text-secondary icon-[lucide--play] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--pause] size-4\" />\n </div>\n\n <!-- Time Display -->\n <div class=\"text-sm font-normal text-nowrap text-base-foreground\">\n {{ formatTime(currentTime) }} / {{ formatTime(duration) }}\n </div>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"relative h-0.5 flex-1 rounded-full bg-interface-stroke\">\n <div\n class=\"absolute top-0 left-0 h-full rounded-full bg-button-icon transition-all\"\n :style=\"{ width: `${progressPercentage}%` }\"\n />\n <input\n type=\"range\"\n :value=\"progressPercentage\"\n min=\"0\"\n max=\"100\"\n step=\"0.1\"\n :aria-label=\"$t('g.audioProgress')\"\n class=\"absolute inset-0 w-full cursor-pointer opacity-0\"\n @input=\"handleSeek\"\n />\n </div>\n\n <!-- Right Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Volume Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.volume')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleMute\"\n >\n <i\n v-if=\"showVolumeTwo\"\n class=\"text-secondary icon-[lucide--volume-2] size-4\"\n />\n <i\n v-else-if=\"showVolumeOne\"\n class=\"text-secondary icon-[lucide--volume-1] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--volume-x] size-4\" />\n </div>\n\n <!-- Options Button -->\n <div\n v-if=\"showOptionsButton\"\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.moreOptions')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleOptionsMenu\"\n >\n <i class=\"text-secondary icon-[lucide--more-vertical] size-4\" />\n </div>\n </div>\n\n <!-- Options Menu -->\n <TieredMenu\n ref=\"optionsMenu\"\n :model=\"menuItems\"\n popup\n class=\"audio-player-menu\"\n :pt:root:class=\"\n cn('bg-component-node-widget-background border-component-node-border')\n \"\n :pt:submenu:class=\"cn('bg-component-node-widget-background')\"\n >\n <template #item=\"{ item }\">\n <div v-if=\"item.key === 'volume'\" class=\"w-48 px-4 py-2\">\n <label class=\"mb-2 block text-xs text-base-foreground\">{{\n item.label\n }}</label>\n <Slider\n :model-value=\"volume * 10\"\n :min=\"0\"\n :max=\"10\"\n :step=\"1\"\n class=\"w-full\"\n @update:model-value=\"handleVolumeChange\"\n />\n </div>\n <div\n v-else\n class=\"flex cursor-pointer items-center px-4 py-2 text-xs hover:bg-white/10\"\n @click=\"item.onClick?.()\"\n >\n <span class=\"text-base-foreground\">{{ item.label }}</span>\n <i\n v-if=\"item.selected\"\n class=\"ml-auto icon-[lucide--check] size-4 text-base-foreground\"\n />\n </div>\n </template>\n </TieredMenu>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Slider from 'primevue/slider'\nimport TieredMenu from 'primevue/tieredmenu'\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\nimport { useI18n } from 'vue-i18n'\n\nimport type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'\nimport { api } from '@/scripts/api'\nimport { app } from '@/scripts/app'\nimport { useNodeOutputStore } from '@/stores/imagePreviewStore'\nimport { getLocatorIdFromNodeData } from '@/utils/graphTraversalUtil'\nimport { isOutputNode } from '@/utils/nodeFilterUtil'\nimport { cn } from '@/utils/tailwindUtil'\n\nimport { formatTime, getResourceURL } from '../../utils/audioUtils'\n\nconst { t } = useI18n()\n\nconst props = withDefaults(\n defineProps<{\n hideWhenEmpty?: boolean\n showOptionsButton?: boolean\n nodeId?: string\n audioUrl?: string\n }>(),\n {\n hideWhenEmpty: true\n }\n)\n\n// Refs\nconst audioRef = ref<HTMLAudioElement>()\nconst optionsMenu = ref()\nconst isPlaying = ref(false)\nconst isMuted = ref(false)\nconst volume = ref(1)\nconst currentTime = ref(0)\nconst duration = ref(0)\nconst hasAudio = ref(false)\nconst playbackRate = ref(1)\n\n// Computed\nconst progressPercentage = computed(() => {\n if (!duration.value || duration.value === 0) return 0\n return (currentTime.value / duration.value) * 100\n})\n\nconst showVolumeTwo = computed(() => !isMuted.value && volume.value > 0.5)\nconst showVolumeOne = computed(() => isMuted.value && volume.value > 0)\n\nconst litegraphNode = computed(() => {\n if (!props.nodeId || !app.canvas.graph) return null\n return app.canvas.graph.getNodeById(props.nodeId) as LGraphNode | null\n})\n\nconst hidden = computed(() => {\n if (!litegraphNode.value) return false\n // dont show if its a LoadAudio and we have nodeId\n const isLoadAudio =\n litegraphNode.value.constructor?.comfyClass === 'LoadAudio'\n return isLoadAudio && !!props.nodeId\n})\n\n// Check if this is an output node\nconst isOutputNodeRef = computed(() => {\n const node = litegraphNode.value\n return !!node && isOutputNode(node)\n})\n\nconst nodeLocatorId = computed(() => {\n const node = litegraphNode.value\n if (!node) return null\n return getLocatorIdFromNodeData(node)\n})\n\nconst nodeOutputStore = useNodeOutputStore()\n\n// Computed audio URL from node output (for output nodes)\nconst audioUrlFromOutput = computed(() => {\n if (!isOutputNodeRef.value || !nodeLocatorId.value) return ''\n\n const nodeOutput = nodeOutputStore.nodeOutputs[nodeLocatorId.value]\n if (!nodeOutput?.audio || nodeOutput.audio.length === 0) return ''\n\n const audio = nodeOutput.audio[0]\n if (!audio.filename) return ''\n\n return api.apiURL(\n getResourceURL(\n audio.subfolder || '',\n audio.filename,\n audio.type || 'output'\n )\n )\n})\n\n// Combined audio URL (output takes precedence for output nodes)\nconst finalAudioUrl = computed(() => {\n return audioUrlFromOutput.value || props.audioUrl || ''\n})\n\n// Playback controls\nconst togglePlayPause = () => {\n if (!audioRef.value || !audioRef.value.src) {\n return\n }\n\n if (isPlaying.value) {\n audioRef.value.pause()\n } else {\n void audioRef.value.play()\n }\n isPlaying.value = !isPlaying.value\n}\n\nconst toggleMute = () => {\n if (audioRef.value) {\n isMuted.value = !isMuted.value\n audioRef.value.muted = isMuted.value\n }\n}\n\nconst handleSeek = (event: Event) => {\n const target = event.target as HTMLInputElement\n const value = parseFloat(target.value)\n if (audioRef.value && duration.value > 0) {\n const newTime = (value / 100) * duration.value\n audioRef.value.currentTime = newTime\n currentTime.value = newTime\n }\n}\n\n// Audio events\nconst handleLoadedMetadata = () => {\n if (audioRef.value) {\n duration.value = audioRef.value.duration\n }\n}\n\nconst handleTimeUpdate = () => {\n if (audioRef.value) {\n currentTime.value = audioRef.value.currentTime\n }\n}\n\nconst handleEnded = () => {\n isPlaying.value = false\n currentTime.value = 0\n}\n\n// Options menu\nconst toggleOptionsMenu = (event: Event) => {\n optionsMenu.value?.toggle(event)\n}\n\nconst setPlaybackSpeed = (speed: number) => {\n playbackRate.value = speed\n if (audioRef.value) {\n audioRef.value.playbackRate = speed\n }\n}\n\nconst handleVolumeChange = (value: number | number[]) => {\n const numValue = Array.isArray(value) ? value[0] : value\n volume.value = numValue / 10\n if (audioRef.value) {\n audioRef.value.volume = volume.value\n if (volume.value > 0 && isMuted.value) {\n isMuted.value = false\n audioRef.value.muted = false\n }\n }\n}\n\nconst menuItems = computed(() => [\n {\n label: t('g.playbackSpeed'),\n items: [\n {\n label: t('g.halfSpeed'),\n onClick: () => setPlaybackSpeed(0.5),\n selected: playbackRate.value === 0.5\n },\n {\n label: t('g.1x'),\n onClick: () => setPlaybackSpeed(1),\n selected: playbackRate.value === 1\n },\n {\n label: t('g.2x'),\n onClick: () => setPlaybackSpeed(2),\n selected: playbackRate.value === 2\n }\n ]\n },\n {\n label: t('g.volume'),\n key: 'volume'\n }\n])\n\n// Load audio from URL\nconst loadAudioFromUrl = (url: string) => {\n if (!audioRef.value) return\n isPlaying.value = false\n audioRef.value.pause()\n audioRef.value.src = url\n void audioRef.value.load()\n hasAudio.value = !!url\n}\n\n// Watch for finalAudioUrl changes\nwatch(\n finalAudioUrl,\n (newUrl) => {\n if (newUrl) {\n void nextTick(() => {\n loadAudioFromUrl(newUrl)\n })\n }\n },\n { immediate: true }\n)\n\n// Cleanup\nonUnmounted(() => {\n if (audioRef.value) {\n audioRef.value.pause()\n audioRef.value.src = ''\n }\n})\n</script>\n\n<style scoped>\n.audio-player-menu {\n --p-tieredmenu-item-focus-background: rgb(255 255 255 / 0.1);\n --p-tieredmenu-item-active-background: rgb(255 255 255 / 0.1);\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AudioPreviewPlayer-BxCSKPl9.js","names":[],"sources":["../../src/renderer/extensions/vueNodes/widgets/components/audio/AudioPreviewPlayer.vue","../../src/renderer/extensions/vueNodes/widgets/components/audio/AudioPreviewPlayer.vue"],"sourcesContent":["<template>\n <div class=\"relative\">\n <div\n v-if=\"!hidden\"\n :class=\"\n cn(\n 'bg-component-node-widget-background box-border flex gap-4 items-center justify-start relative rounded-lg w-full h-16 px-4 py-0',\n { hidden: hideWhenEmpty && !hasAudio }\n )\n \"\n >\n <!-- Hidden audio element -->\n <audio\n ref=\"audioRef\"\n @loadedmetadata=\"handleLoadedMetadata\"\n @timeupdate=\"handleTimeUpdate\"\n @ended=\"handleEnded\"\n />\n\n <!-- Left Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Play/Pause Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.playPause')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"togglePlayPause\"\n >\n <i\n v-if=\"!isPlaying\"\n class=\"text-secondary icon-[lucide--play] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--pause] size-4\" />\n </div>\n\n <!-- Time Display -->\n <div class=\"text-sm font-normal text-nowrap text-base-foreground\">\n {{ formatTime(currentTime) }} / {{ formatTime(duration) }}\n </div>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"relative h-0.5 flex-1 rounded-full bg-interface-stroke\">\n <div\n class=\"absolute top-0 left-0 h-full rounded-full bg-button-icon transition-all\"\n :style=\"{ width: `${progressPercentage}%` }\"\n />\n <input\n type=\"range\"\n :value=\"progressPercentage\"\n min=\"0\"\n max=\"100\"\n step=\"0.1\"\n :aria-label=\"$t('g.audioProgress')\"\n class=\"absolute inset-0 w-full cursor-pointer opacity-0\"\n @input=\"handleSeek\"\n />\n </div>\n\n <!-- Right Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Volume Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.volume')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleMute\"\n >\n <i\n v-if=\"showVolumeTwo\"\n class=\"text-secondary icon-[lucide--volume-2] size-4\"\n />\n <i\n v-else-if=\"showVolumeOne\"\n class=\"text-secondary icon-[lucide--volume-1] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--volume-x] size-4\" />\n </div>\n\n <!-- Options Button -->\n <div\n v-if=\"showOptionsButton\"\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.moreOptions')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleOptionsMenu\"\n >\n <i class=\"text-secondary icon-[lucide--more-vertical] size-4\" />\n </div>\n </div>\n\n <!-- Options Menu -->\n <TieredMenu\n ref=\"optionsMenu\"\n :model=\"menuItems\"\n popup\n class=\"audio-player-menu\"\n :pt:root:class=\"\n cn('bg-component-node-widget-background border-component-node-border')\n \"\n :pt:submenu:class=\"cn('bg-component-node-widget-background')\"\n >\n <template #item=\"{ item }\">\n <div v-if=\"item.key === 'volume'\" class=\"w-48 px-4 py-2\">\n <label class=\"mb-2 block text-xs text-base-foreground\">{{\n item.label\n }}</label>\n <Slider\n :model-value=\"volume * 10\"\n :min=\"0\"\n :max=\"10\"\n :step=\"1\"\n class=\"w-full\"\n @update:model-value=\"handleVolumeChange\"\n />\n </div>\n <div\n v-else\n class=\"flex cursor-pointer items-center px-4 py-2 text-xs hover:bg-white/10\"\n @click=\"item.onClick?.()\"\n >\n <span class=\"text-base-foreground\">{{ item.label }}</span>\n <i\n v-if=\"item.selected\"\n class=\"ml-auto icon-[lucide--check] size-4 text-base-foreground\"\n />\n </div>\n </template>\n </TieredMenu>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Slider from 'primevue/slider'\nimport TieredMenu from 'primevue/tieredmenu'\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\nimport { useI18n } from 'vue-i18n'\n\nimport type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'\nimport { api } from '@/scripts/api'\nimport { app } from '@/scripts/app'\nimport { useNodeOutputStore } from '@/stores/imagePreviewStore'\nimport { getLocatorIdFromNodeData } from '@/utils/graphTraversalUtil'\nimport { isOutputNode } from '@/utils/nodeFilterUtil'\nimport { cn } from '@/utils/tailwindUtil'\n\nimport { formatTime, getResourceURL } from '../../utils/audioUtils'\n\nconst { t } = useI18n()\n\nconst props = withDefaults(\n defineProps<{\n hideWhenEmpty?: boolean\n showOptionsButton?: boolean\n nodeId?: string\n audioUrl?: string\n }>(),\n {\n hideWhenEmpty: true\n }\n)\n\n// Refs\nconst audioRef = ref<HTMLAudioElement>()\nconst optionsMenu = ref()\nconst isPlaying = ref(false)\nconst isMuted = ref(false)\nconst volume = ref(1)\nconst currentTime = ref(0)\nconst duration = ref(0)\nconst hasAudio = ref(false)\nconst playbackRate = ref(1)\n\n// Computed\nconst progressPercentage = computed(() => {\n if (!duration.value || duration.value === 0) return 0\n return (currentTime.value / duration.value) * 100\n})\n\nconst showVolumeTwo = computed(() => !isMuted.value && volume.value > 0.5)\nconst showVolumeOne = computed(() => isMuted.value && volume.value > 0)\n\nconst litegraphNode = computed(() => {\n if (!props.nodeId || !app.canvas.graph) return null\n return app.canvas.graph.getNodeById(props.nodeId) as LGraphNode | null\n})\n\nconst hidden = computed(() => {\n if (!litegraphNode.value) return false\n // dont show if its a LoadAudio and we have nodeId\n const isLoadAudio =\n litegraphNode.value.constructor?.comfyClass === 'LoadAudio'\n return isLoadAudio && !!props.nodeId\n})\n\n// Check if this is an output node\nconst isOutputNodeRef = computed(() => {\n const node = litegraphNode.value\n return !!node && isOutputNode(node)\n})\n\nconst nodeLocatorId = computed(() => {\n const node = litegraphNode.value\n if (!node) return null\n return getLocatorIdFromNodeData(node)\n})\n\nconst nodeOutputStore = useNodeOutputStore()\n\n// Computed audio URL from node output (for output nodes)\nconst audioUrlFromOutput = computed(() => {\n if (!isOutputNodeRef.value || !nodeLocatorId.value) return ''\n\n const nodeOutput = nodeOutputStore.nodeOutputs[nodeLocatorId.value]\n if (!nodeOutput?.audio || nodeOutput.audio.length === 0) return ''\n\n const audio = nodeOutput.audio[0]\n if (!audio.filename) return ''\n\n return api.apiURL(\n getResourceURL(\n audio.subfolder || '',\n audio.filename,\n audio.type || 'output'\n )\n )\n})\n\n// Combined audio URL (output takes precedence for output nodes)\nconst finalAudioUrl = computed(() => {\n return audioUrlFromOutput.value || props.audioUrl || ''\n})\n\n// Playback controls\nconst togglePlayPause = () => {\n if (!audioRef.value || !audioRef.value.src) {\n return\n }\n\n if (isPlaying.value) {\n audioRef.value.pause()\n } else {\n void audioRef.value.play()\n }\n isPlaying.value = !isPlaying.value\n}\n\nconst toggleMute = () => {\n if (audioRef.value) {\n isMuted.value = !isMuted.value\n audioRef.value.muted = isMuted.value\n }\n}\n\nconst handleSeek = (event: Event) => {\n const target = event.target as HTMLInputElement\n const value = parseFloat(target.value)\n if (audioRef.value && duration.value > 0) {\n const newTime = (value / 100) * duration.value\n audioRef.value.currentTime = newTime\n currentTime.value = newTime\n }\n}\n\n// Audio events\nconst handleLoadedMetadata = () => {\n if (audioRef.value) {\n duration.value = audioRef.value.duration\n }\n}\n\nconst handleTimeUpdate = () => {\n if (audioRef.value) {\n currentTime.value = audioRef.value.currentTime\n }\n}\n\nconst handleEnded = () => {\n isPlaying.value = false\n currentTime.value = 0\n}\n\n// Options menu\nconst toggleOptionsMenu = (event: Event) => {\n optionsMenu.value?.toggle(event)\n}\n\nconst setPlaybackSpeed = (speed: number) => {\n playbackRate.value = speed\n if (audioRef.value) {\n audioRef.value.playbackRate = speed\n }\n}\n\nconst handleVolumeChange = (value: number | number[]) => {\n const numValue = Array.isArray(value) ? value[0] : value\n volume.value = numValue / 10\n if (audioRef.value) {\n audioRef.value.volume = volume.value\n if (volume.value > 0 && isMuted.value) {\n isMuted.value = false\n audioRef.value.muted = false\n }\n }\n}\n\nconst menuItems = computed(() => [\n {\n label: t('g.playbackSpeed'),\n items: [\n {\n label: t('g.halfSpeed'),\n onClick: () => setPlaybackSpeed(0.5),\n selected: playbackRate.value === 0.5\n },\n {\n label: t('g.1x'),\n onClick: () => setPlaybackSpeed(1),\n selected: playbackRate.value === 1\n },\n {\n label: t('g.2x'),\n onClick: () => setPlaybackSpeed(2),\n selected: playbackRate.value === 2\n }\n ]\n },\n {\n label: t('g.volume'),\n key: 'volume'\n }\n])\n\n// Load audio from URL\nconst loadAudioFromUrl = (url: string) => {\n if (!audioRef.value) return\n isPlaying.value = false\n audioRef.value.pause()\n audioRef.value.src = url\n void audioRef.value.load()\n hasAudio.value = !!url\n}\n\n// Watch for finalAudioUrl changes\nwatch(\n finalAudioUrl,\n (newUrl) => {\n if (newUrl) {\n void nextTick(() => {\n loadAudioFromUrl(newUrl)\n })\n }\n },\n { immediate: true }\n)\n\n// Cleanup\nonUnmounted(() => {\n if (audioRef.value) {\n audioRef.value.pause()\n audioRef.value.src = ''\n }\n})\n</script>\n\n<style scoped>\n.audio-player-menu {\n --p-tieredmenu-item-focus-background: rgb(255 255 255 / 0.1);\n --p-tieredmenu-item-active-background: rgb(255 255 255 / 0.1);\n}\n</style>\n","<template>\n <div class=\"relative\">\n <div\n v-if=\"!hidden\"\n :class=\"\n cn(\n 'bg-component-node-widget-background box-border flex gap-4 items-center justify-start relative rounded-lg w-full h-16 px-4 py-0',\n { hidden: hideWhenEmpty && !hasAudio }\n )\n \"\n >\n <!-- Hidden audio element -->\n <audio\n ref=\"audioRef\"\n @loadedmetadata=\"handleLoadedMetadata\"\n @timeupdate=\"handleTimeUpdate\"\n @ended=\"handleEnded\"\n />\n\n <!-- Left Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Play/Pause Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.playPause')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"togglePlayPause\"\n >\n <i\n v-if=\"!isPlaying\"\n class=\"text-secondary icon-[lucide--play] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--pause] size-4\" />\n </div>\n\n <!-- Time Display -->\n <div class=\"text-sm font-normal text-nowrap text-base-foreground\">\n {{ formatTime(currentTime) }} / {{ formatTime(duration) }}\n </div>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"relative h-0.5 flex-1 rounded-full bg-interface-stroke\">\n <div\n class=\"absolute top-0 left-0 h-full rounded-full bg-button-icon transition-all\"\n :style=\"{ width: `${progressPercentage}%` }\"\n />\n <input\n type=\"range\"\n :value=\"progressPercentage\"\n min=\"0\"\n max=\"100\"\n step=\"0.1\"\n :aria-label=\"$t('g.audioProgress')\"\n class=\"absolute inset-0 w-full cursor-pointer opacity-0\"\n @input=\"handleSeek\"\n />\n </div>\n\n <!-- Right Actions -->\n <div class=\"relative flex shrink-0 items-center justify-start gap-2\">\n <!-- Volume Button -->\n <div\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.volume')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleMute\"\n >\n <i\n v-if=\"showVolumeTwo\"\n class=\"text-secondary icon-[lucide--volume-2] size-4\"\n />\n <i\n v-else-if=\"showVolumeOne\"\n class=\"text-secondary icon-[lucide--volume-1] size-4\"\n />\n <i v-else class=\"text-secondary icon-[lucide--volume-x] size-4\" />\n </div>\n\n <!-- Options Button -->\n <div\n v-if=\"showOptionsButton\"\n role=\"button\"\n :tabindex=\"0\"\n :aria-label=\"$t('g.moreOptions')\"\n class=\"flex size-6 cursor-pointer items-center justify-center rounded hover:bg-interface-menu-component-surface-hovered\"\n @click=\"toggleOptionsMenu\"\n >\n <i class=\"text-secondary icon-[lucide--more-vertical] size-4\" />\n </div>\n </div>\n\n <!-- Options Menu -->\n <TieredMenu\n ref=\"optionsMenu\"\n :model=\"menuItems\"\n popup\n class=\"audio-player-menu\"\n :pt:root:class=\"\n cn('bg-component-node-widget-background border-component-node-border')\n \"\n :pt:submenu:class=\"cn('bg-component-node-widget-background')\"\n >\n <template #item=\"{ item }\">\n <div v-if=\"item.key === 'volume'\" class=\"w-48 px-4 py-2\">\n <label class=\"mb-2 block text-xs text-base-foreground\">{{\n item.label\n }}</label>\n <Slider\n :model-value=\"volume * 10\"\n :min=\"0\"\n :max=\"10\"\n :step=\"1\"\n class=\"w-full\"\n @update:model-value=\"handleVolumeChange\"\n />\n </div>\n <div\n v-else\n class=\"flex cursor-pointer items-center px-4 py-2 text-xs hover:bg-white/10\"\n @click=\"item.onClick?.()\"\n >\n <span class=\"text-base-foreground\">{{ item.label }}</span>\n <i\n v-if=\"item.selected\"\n class=\"ml-auto icon-[lucide--check] size-4 text-base-foreground\"\n />\n </div>\n </template>\n </TieredMenu>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Slider from 'primevue/slider'\nimport TieredMenu from 'primevue/tieredmenu'\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\nimport { useI18n } from 'vue-i18n'\n\nimport type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'\nimport { api } from '@/scripts/api'\nimport { app } from '@/scripts/app'\nimport { useNodeOutputStore } from '@/stores/imagePreviewStore'\nimport { getLocatorIdFromNodeData } from '@/utils/graphTraversalUtil'\nimport { isOutputNode } from '@/utils/nodeFilterUtil'\nimport { cn } from '@/utils/tailwindUtil'\n\nimport { formatTime, getResourceURL } from '../../utils/audioUtils'\n\nconst { t } = useI18n()\n\nconst props = withDefaults(\n defineProps<{\n hideWhenEmpty?: boolean\n showOptionsButton?: boolean\n nodeId?: string\n audioUrl?: string\n }>(),\n {\n hideWhenEmpty: true\n }\n)\n\n// Refs\nconst audioRef = ref<HTMLAudioElement>()\nconst optionsMenu = ref()\nconst isPlaying = ref(false)\nconst isMuted = ref(false)\nconst volume = ref(1)\nconst currentTime = ref(0)\nconst duration = ref(0)\nconst hasAudio = ref(false)\nconst playbackRate = ref(1)\n\n// Computed\nconst progressPercentage = computed(() => {\n if (!duration.value || duration.value === 0) return 0\n return (currentTime.value / duration.value) * 100\n})\n\nconst showVolumeTwo = computed(() => !isMuted.value && volume.value > 0.5)\nconst showVolumeOne = computed(() => isMuted.value && volume.value > 0)\n\nconst litegraphNode = computed(() => {\n if (!props.nodeId || !app.canvas.graph) return null\n return app.canvas.graph.getNodeById(props.nodeId) as LGraphNode | null\n})\n\nconst hidden = computed(() => {\n if (!litegraphNode.value) return false\n // dont show if its a LoadAudio and we have nodeId\n const isLoadAudio =\n litegraphNode.value.constructor?.comfyClass === 'LoadAudio'\n return isLoadAudio && !!props.nodeId\n})\n\n// Check if this is an output node\nconst isOutputNodeRef = computed(() => {\n const node = litegraphNode.value\n return !!node && isOutputNode(node)\n})\n\nconst nodeLocatorId = computed(() => {\n const node = litegraphNode.value\n if (!node) return null\n return getLocatorIdFromNodeData(node)\n})\n\nconst nodeOutputStore = useNodeOutputStore()\n\n// Computed audio URL from node output (for output nodes)\nconst audioUrlFromOutput = computed(() => {\n if (!isOutputNodeRef.value || !nodeLocatorId.value) return ''\n\n const nodeOutput = nodeOutputStore.nodeOutputs[nodeLocatorId.value]\n if (!nodeOutput?.audio || nodeOutput.audio.length === 0) return ''\n\n const audio = nodeOutput.audio[0]\n if (!audio.filename) return ''\n\n return api.apiURL(\n getResourceURL(\n audio.subfolder || '',\n audio.filename,\n audio.type || 'output'\n )\n )\n})\n\n// Combined audio URL (output takes precedence for output nodes)\nconst finalAudioUrl = computed(() => {\n return audioUrlFromOutput.value || props.audioUrl || ''\n})\n\n// Playback controls\nconst togglePlayPause = () => {\n if (!audioRef.value || !audioRef.value.src) {\n return\n }\n\n if (isPlaying.value) {\n audioRef.value.pause()\n } else {\n void audioRef.value.play()\n }\n isPlaying.value = !isPlaying.value\n}\n\nconst toggleMute = () => {\n if (audioRef.value) {\n isMuted.value = !isMuted.value\n audioRef.value.muted = isMuted.value\n }\n}\n\nconst handleSeek = (event: Event) => {\n const target = event.target as HTMLInputElement\n const value = parseFloat(target.value)\n if (audioRef.value && duration.value > 0) {\n const newTime = (value / 100) * duration.value\n audioRef.value.currentTime = newTime\n currentTime.value = newTime\n }\n}\n\n// Audio events\nconst handleLoadedMetadata = () => {\n if (audioRef.value) {\n duration.value = audioRef.value.duration\n }\n}\n\nconst handleTimeUpdate = () => {\n if (audioRef.value) {\n currentTime.value = audioRef.value.currentTime\n }\n}\n\nconst handleEnded = () => {\n isPlaying.value = false\n currentTime.value = 0\n}\n\n// Options menu\nconst toggleOptionsMenu = (event: Event) => {\n optionsMenu.value?.toggle(event)\n}\n\nconst setPlaybackSpeed = (speed: number) => {\n playbackRate.value = speed\n if (audioRef.value) {\n audioRef.value.playbackRate = speed\n }\n}\n\nconst handleVolumeChange = (value: number | number[]) => {\n const numValue = Array.isArray(value) ? value[0] : value\n volume.value = numValue / 10\n if (audioRef.value) {\n audioRef.value.volume = volume.value\n if (volume.value > 0 && isMuted.value) {\n isMuted.value = false\n audioRef.value.muted = false\n }\n }\n}\n\nconst menuItems = computed(() => [\n {\n label: t('g.playbackSpeed'),\n items: [\n {\n label: t('g.halfSpeed'),\n onClick: () => setPlaybackSpeed(0.5),\n selected: playbackRate.value === 0.5\n },\n {\n label: t('g.1x'),\n onClick: () => setPlaybackSpeed(1),\n selected: playbackRate.value === 1\n },\n {\n label: t('g.2x'),\n onClick: () => setPlaybackSpeed(2),\n selected: playbackRate.value === 2\n }\n ]\n },\n {\n label: t('g.volume'),\n key: 'volume'\n }\n])\n\n// Load audio from URL\nconst loadAudioFromUrl = (url: string) => {\n if (!audioRef.value) return\n isPlaying.value = false\n audioRef.value.pause()\n audioRef.value.src = url\n void audioRef.value.load()\n hasAudio.value = !!url\n}\n\n// Watch for finalAudioUrl changes\nwatch(\n finalAudioUrl,\n (newUrl) => {\n if (newUrl) {\n void nextTick(() => {\n loadAudioFromUrl(newUrl)\n })\n }\n },\n { immediate: true }\n)\n\n// Cleanup\nonUnmounted(() => {\n if (audioRef.value) {\n audioRef.value.pause()\n audioRef.value.src = ''\n }\n})\n</script>\n\n<style scoped>\n.audio-player-menu {\n --p-tieredmenu-item-focus-background: rgb(255 255 255 / 0.1);\n --p-tieredmenu-item-active-background: rgb(255 255 255 / 0.1);\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./vendor-primevue-DcMRXJN3.js";import"./vendor-other-DlQF6V2E.js";import"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import"./Button-Do2I1OAA.js";import"./PanelTemplate-BJda9e5J.js";import"./dialogService-YG0RH337.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BAS9m9W6.js";import"./audioUtils-DD4rUYVZ.js";import{t as x}from"./AudioPreviewPlayer-BxCSKPl9.js";export{x as default};
|
comfyui_frontend_package/static/assets/{BaseViewTemplate-DA6zfigT.js → BaseViewTemplate-CjODF2hh.js}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Aa as l,Ba as t,Jo as n,Oo as i,Ua as c,Xo as u,Ya as d,co as f,do as m,io as p,mo as h,zo as g}from"./vendor-other-DlQF6V2E.js";import{Bt as v,Vt as _,zt as w}from"./api-
|
|
1
|
+
import{Aa as l,Ba as t,Jo as n,Oo as i,Ua as c,Xo as u,Ya as d,co as f,do as m,io as p,mo as h,zo as g}from"./vendor-other-DlQF6V2E.js";import{Bt as v,Vt as _,zt as w}from"./api-Dwq2LQIW.js";var B={class:"flex w-full grow items-center justify-center overflow-auto"},k=d({__name:"BaseViewTemplate",props:{dark:{type:Boolean,default:!1}},setup(o){const s={color:"rgba(0, 0, 0, 0)",symbolColor:"#d4d4d4"},r={color:"rgba(0, 0, 0, 0)",symbolColor:"#171717"},e=g(null);return f(async()=>{v()&&(await p(),w().changeTheme({...o.dark?s:r,height:e.value?.getBoundingClientRect().height??0}))}),(a,y)=>(m(),c("div",{class:u(["flex h-svh w-screen flex-col font-sans",[a.dark?"dark-theme bg-neutral-900 text-neutral-300":"bg-neutral-300 text-neutral-900"]])},[i(t("div",{ref_key:"topMenuRef",ref:e,class:"app-drag h-(--comfy-topbar-height) w-full"},null,512),[[l,n(_)()]]),t("div",B,[h(a.$slots,"default")])],2))}}),x=k;export{x as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=BaseViewTemplate-
|
|
3
|
+
//# sourceMappingURL=BaseViewTemplate-CjODF2hh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseViewTemplate-
|
|
1
|
+
{"version":3,"file":"BaseViewTemplate-CjODF2hh.js","names":[],"sources":["../../src/views/templates/BaseViewTemplate.vue","../../src/views/templates/BaseViewTemplate.vue"],"sourcesContent":["<template>\n <div\n class=\"flex h-svh w-screen flex-col font-sans\"\n :class=\"[\n dark\n ? 'dark-theme bg-neutral-900 text-neutral-300'\n : 'bg-neutral-300 text-neutral-900'\n ]\"\n >\n <!-- Virtual top menu for native window (drag handle) -->\n <div\n v-show=\"isNativeWindow()\"\n ref=\"topMenuRef\"\n class=\"app-drag h-(--comfy-topbar-height) w-full\"\n />\n <div class=\"flex w-full grow items-center justify-center overflow-auto\">\n <slot />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { nextTick, onMounted, ref } from 'vue'\n\nimport { electronAPI, isElectron, isNativeWindow } from '@/utils/envUtil'\n\nconst { dark = false } = defineProps<{\n dark?: boolean\n}>()\n\nconst darkTheme = {\n color: 'rgba(0, 0, 0, 0)',\n symbolColor: '#d4d4d4'\n}\n\nconst lightTheme = {\n color: 'rgba(0, 0, 0, 0)',\n symbolColor: '#171717'\n}\n\nconst topMenuRef = ref<HTMLDivElement | null>(null)\nonMounted(async () => {\n if (isElectron()) {\n await nextTick()\n\n electronAPI().changeTheme({\n ...(dark ? darkTheme : lightTheme),\n height: topMenuRef.value?.getBoundingClientRect().height ?? 0\n })\n }\n})\n</script>\n","<template>\n <div\n class=\"flex h-svh w-screen flex-col font-sans\"\n :class=\"[\n dark\n ? 'dark-theme bg-neutral-900 text-neutral-300'\n : 'bg-neutral-300 text-neutral-900'\n ]\"\n >\n <!-- Virtual top menu for native window (drag handle) -->\n <div\n v-show=\"isNativeWindow()\"\n ref=\"topMenuRef\"\n class=\"app-drag h-(--comfy-topbar-height) w-full\"\n />\n <div class=\"flex w-full grow items-center justify-center overflow-auto\">\n <slot />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { nextTick, onMounted, ref } from 'vue'\n\nimport { electronAPI, isElectron, isNativeWindow } from '@/utils/envUtil'\n\nconst { dark = false } = defineProps<{\n dark?: boolean\n}>()\n\nconst darkTheme = {\n color: 'rgba(0, 0, 0, 0)',\n symbolColor: '#d4d4d4'\n}\n\nconst lightTheme = {\n color: 'rgba(0, 0, 0, 0)',\n symbolColor: '#171717'\n}\n\nconst topMenuRef = ref<HTMLDivElement | null>(null)\nonMounted(async () => {\n if (isElectron()) {\n await nextTick()\n\n electronAPI().changeTheme({\n ...(dark ? darkTheme : lightTheme),\n height: topMenuRef.value?.getBoundingClientRect().height ?? 0\n })\n }\n})\n</script>\n"],"mappings":"yVC8BA,MAAM,EAAY,CAChB,MAAO,mBACP,YAAa,WAGT,EAAa,CACjB,MAAO,mBACP,YAAa,WAGT,EAAa,EAA2B,IAAA,EAC9C,OAAA,EAAU,SAAY,CAChB,EAAA,IACF,MAAM,EAAA,EAEN,EAAA,EAAc,YAAY,CACxB,GAAI,EAAA,KAAO,EAAY,EACvB,OAAQ,EAAW,OAAO,sBAAA,EAAwB,QAAU,EAC7D"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var g=Object.defineProperty;var m=(n,u)=>g(n,"name",{value:u,configurable:!0});import"./vendor-primevue-DcMRXJN3.js";import{$o as o,Ba as e,Do as v,Ha as p,Ka as i,Pa as f,Ua as a,Xo as x,Ya as _,do as s,po as y,qa as k,zo as w}from"./vendor-other-DlQF6V2E.js";import{c as T}from"./vendor-vue-D9IUuwPJ.js";import"./api-
|
|
1
|
+
var g=Object.defineProperty;var m=(n,u)=>g(n,"name",{value:u,configurable:!0});import"./vendor-primevue-DcMRXJN3.js";import{$o as o,Ba as e,Do as v,Ha as p,Ka as i,Pa as f,Ua as a,Xo as x,Ya as _,do as s,po as y,qa as k,zo as w}from"./vendor-other-DlQF6V2E.js";import{c as T}from"./vendor-vue-D9IUuwPJ.js";import"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import{t as $}from"./Button-Do2I1OAA.js";import"./PanelTemplate-BJda9e5J.js";import{Mr as C}from"./dialogService-YG0RH337.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BAS9m9W6.js";var O={class:"flex h-full items-center justify-center p-6"},V={class:"max-w-[100vw] text-center lg:w-[500px]"},A={class:"mb-3 text-xl text-text-primary"},B={class:"mb-5 text-muted"},D={class:"mb-4 rounded bg-secondary-background px-3 py-2 text-left"},M={class:"mb-2 text-sm font-semibold text-text-primary"},N={class:"space-y-1.5 text-sm text-muted"},j={key:0,class:"mb-4 text-left"},z={key:0,class:"mt-2 rounded border-muted-background border p-4 font-mono text-xs text-muted-foreground break-all"},F={class:"mb-5 text-center text-sm text-gray-600"},L={href:"https://support.comfy.org",class:"cursor-pointer text-blue-400 no-underline",target:"_blank",rel:"noopener noreferrer"},R={class:"flex flex-col gap-3"},q=_({__name:"CloudAuthTimeoutView",props:{errorMessage:{}},setup(n){const u=T(),{logout:c}=C(),l=w(!1),h=m(async()=>{await c(),await u.replace({name:"cloud-login"})},"handleRestart");return(t,r)=>(s(),a("div",O,[e("div",V,[e("h2",A,o(t.$t("cloudOnboarding.authTimeout.title")),1),e("p",B,o(t.$t("cloudOnboarding.authTimeout.message")),1),e("div",D,[e("h3",M,o(t.$t("cloudOnboarding.authTimeout.troubleshooting")),1),e("ul",N,[(s(!0),a(f,null,y(t.$tm("cloudOnboarding.authTimeout.causes"),(d,b)=>(s(),a("li",{key:b,class:"flex gap-2"},[r[1]||(r[1]=e("span",null,"•",-1)),e("span",null,o(d),1)]))),128))])]),t.errorMessage?(s(),a("div",j,[e("button",{class:"flex w-full items-center justify-between rounded bg-secondary-background px-4 py-2 text-sm text-text-secondary transition-colors hover:bg-secondary-background-hover border-0",onClick:r[0]||(r[0]=d=>l.value=!l.value)},[e("span",null,o(t.$t("cloudOnboarding.authTimeout.technicalDetails")),1),e("i",{class:x(["pi",l.value?"pi-chevron-up":"pi-chevron-down"])},null,2)]),l.value?(s(),a("div",z,o(t.errorMessage),1)):p("",!0)])):p("",!0),e("p",F,[i(o(t.$t("cloudOnboarding.authTimeout.helpText"))+" ",1),e("a",L,o(t.$t("cloudOnboarding.authTimeout.supportLink")),1),r[2]||(r[2]=i(". "))]),e("div",R,[k($,{class:"w-full",onClick:h},{default:v(()=>[i(o(t.$t("cloudOnboarding.authTimeout.restart")),1)]),_:1})])])]))}}),oe=q;export{oe as default};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=CloudAuthTimeoutView-
|
|
3
|
+
//# sourceMappingURL=CloudAuthTimeoutView-D-QkjPNh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudAuthTimeoutView-
|
|
1
|
+
{"version":3,"file":"CloudAuthTimeoutView-D-QkjPNh.js","names":[],"sources":["../../src/platform/cloud/onboarding/CloudAuthTimeoutView.vue","../../src/platform/cloud/onboarding/CloudAuthTimeoutView.vue"],"sourcesContent":["<template>\n <div class=\"flex h-full items-center justify-center p-6\">\n <div class=\"max-w-[100vw] text-center lg:w-[500px]\">\n <h2 class=\"mb-3 text-xl text-text-primary\">\n {{ $t('cloudOnboarding.authTimeout.title') }}\n </h2>\n <p class=\"mb-5 text-muted\">\n {{ $t('cloudOnboarding.authTimeout.message') }}\n </p>\n\n <!-- Troubleshooting Section -->\n <div class=\"mb-4 rounded bg-secondary-background px-3 py-2 text-left\">\n <h3 class=\"mb-2 text-sm font-semibold text-text-primary\">\n {{ $t('cloudOnboarding.authTimeout.troubleshooting') }}\n </h3>\n <ul class=\"space-y-1.5 text-sm text-muted\">\n <li\n v-for=\"(cause, index) in $tm('cloudOnboarding.authTimeout.causes')\"\n :key=\"index\"\n class=\"flex gap-2\"\n >\n <span>•</span>\n <span>{{ cause }}</span>\n </li>\n </ul>\n </div>\n\n <!-- Technical Details (Collapsible) -->\n <div v-if=\"errorMessage\" class=\"mb-4 text-left\">\n <button\n class=\"flex w-full items-center justify-between rounded bg-secondary-background px-4 py-2 text-sm text-text-secondary transition-colors hover:bg-secondary-background-hover border-0\"\n @click=\"showTechnicalDetails = !showTechnicalDetails\"\n >\n <span>{{ $t('cloudOnboarding.authTimeout.technicalDetails') }}</span>\n <i\n :class=\"[\n 'pi',\n showTechnicalDetails ? 'pi-chevron-up' : 'pi-chevron-down'\n ]\"\n ></i>\n </button>\n <div\n v-if=\"showTechnicalDetails\"\n class=\"mt-2 rounded border-muted-background border p-4 font-mono text-xs text-muted-foreground break-all\"\n >\n {{ errorMessage }}\n </div>\n </div>\n\n <!-- Helpful Links -->\n <p class=\"mb-5 text-center text-sm text-gray-600\">\n {{ $t('cloudOnboarding.authTimeout.helpText') }}\n <a\n href=\"https://support.comfy.org\"\n class=\"cursor-pointer text-blue-400 no-underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {{ $t('cloudOnboarding.authTimeout.supportLink') }}</a\n >.\n </p>\n\n <div class=\"flex flex-col gap-3\">\n <Button class=\"w-full\" @click=\"handleRestart\">\n {{ $t('cloudOnboarding.authTimeout.restart') }}\n </Button>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport Button from '@/components/ui/button/Button.vue'\nimport { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'\n\ninterface Props {\n errorMessage?: string\n}\n\ndefineProps<Props>()\n\nconst router = useRouter()\nconst { logout } = useFirebaseAuthActions()\nconst showTechnicalDetails = ref(false)\n\nconst handleRestart = async () => {\n await logout()\n await router.replace({ name: 'cloud-login' })\n}\n</script>\n","<template>\n <div class=\"flex h-full items-center justify-center p-6\">\n <div class=\"max-w-[100vw] text-center lg:w-[500px]\">\n <h2 class=\"mb-3 text-xl text-text-primary\">\n {{ $t('cloudOnboarding.authTimeout.title') }}\n </h2>\n <p class=\"mb-5 text-muted\">\n {{ $t('cloudOnboarding.authTimeout.message') }}\n </p>\n\n <!-- Troubleshooting Section -->\n <div class=\"mb-4 rounded bg-secondary-background px-3 py-2 text-left\">\n <h3 class=\"mb-2 text-sm font-semibold text-text-primary\">\n {{ $t('cloudOnboarding.authTimeout.troubleshooting') }}\n </h3>\n <ul class=\"space-y-1.5 text-sm text-muted\">\n <li\n v-for=\"(cause, index) in $tm('cloudOnboarding.authTimeout.causes')\"\n :key=\"index\"\n class=\"flex gap-2\"\n >\n <span>•</span>\n <span>{{ cause }}</span>\n </li>\n </ul>\n </div>\n\n <!-- Technical Details (Collapsible) -->\n <div v-if=\"errorMessage\" class=\"mb-4 text-left\">\n <button\n class=\"flex w-full items-center justify-between rounded bg-secondary-background px-4 py-2 text-sm text-text-secondary transition-colors hover:bg-secondary-background-hover border-0\"\n @click=\"showTechnicalDetails = !showTechnicalDetails\"\n >\n <span>{{ $t('cloudOnboarding.authTimeout.technicalDetails') }}</span>\n <i\n :class=\"[\n 'pi',\n showTechnicalDetails ? 'pi-chevron-up' : 'pi-chevron-down'\n ]\"\n ></i>\n </button>\n <div\n v-if=\"showTechnicalDetails\"\n class=\"mt-2 rounded border-muted-background border p-4 font-mono text-xs text-muted-foreground break-all\"\n >\n {{ errorMessage }}\n </div>\n </div>\n\n <!-- Helpful Links -->\n <p class=\"mb-5 text-center text-sm text-gray-600\">\n {{ $t('cloudOnboarding.authTimeout.helpText') }}\n <a\n href=\"https://support.comfy.org\"\n class=\"cursor-pointer text-blue-400 no-underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {{ $t('cloudOnboarding.authTimeout.supportLink') }}</a\n >.\n </p>\n\n <div class=\"flex flex-col gap-3\">\n <Button class=\"w-full\" @click=\"handleRestart\">\n {{ $t('cloudOnboarding.authTimeout.restart') }}\n </Button>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { useRouter } from 'vue-router'\n\nimport Button from '@/components/ui/button/Button.vue'\nimport { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'\n\ninterface Props {\n errorMessage?: string\n}\n\ndefineProps<Props>()\n\nconst router = useRouter()\nconst { logout } = useFirebaseAuthActions()\nconst showTechnicalDetails = ref(false)\n\nconst handleRestart = async () => {\n await logout()\n await router.replace({ name: 'cloud-login' })\n}\n</script>\n"],"mappings":"q/CCoFA,MAAM,EAAS,EAAA,EACT,CAAE,OAAA,CAAA,EAAW,EAAA,EACb,EAAuB,EAAI,EAAA,EAE3B,EAAgB,EAAA,SAAY,CAChC,MAAM,EAAA,EACN,MAAM,EAAO,QAAQ,CAAE,KAAM,aAAA,CAAe,GAFxB"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Va as o,Ya as d,do as r,za as l}from"./vendor-other-DlQF6V2E.js";import{A as u}from"./api-
|
|
1
|
+
import{Va as o,Ya as d,do as r,za as l}from"./vendor-other-DlQF6V2E.js";import{A as u}from"./api-Dwq2LQIW.js";import{n}from"./SubscribeButton-DZBycfCA.js";var t=d({__name:"CloudBadge",props:{displayMode:{default:"full"},reverseOrder:{type:Boolean,default:!1},noPadding:{type:Boolean,default:!1},backgroundColor:{default:"var(--comfy-menu-bg)"}},setup(p){const a=l(()=>({label:u("g.beta"),text:"Comfy Cloud"}));return(e,s)=>(r(),o(n,{badge:a.value,"display-mode":e.displayMode,"reverse-order":e.reverseOrder,"no-padding":e.noPadding,"background-color":e.backgroundColor},null,8,["badge","display-mode","reverse-order","no-padding","background-color"]))}}),c=t;export{c as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=CloudBadge-
|
|
3
|
+
//# sourceMappingURL=CloudBadge-B4nmLus2.js.map
|
comfyui_frontend_package/static/assets/{CloudBadge-BnLiAHDN.js.map → CloudBadge-B4nmLus2.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudBadge-
|
|
1
|
+
{"version":3,"file":"CloudBadge-B4nmLus2.js","names":[],"sources":["../../src/components/topbar/CloudBadge.vue","../../src/components/topbar/CloudBadge.vue"],"sourcesContent":["<template>\n <TopbarBadge\n :badge=\"cloudBadge\"\n :display-mode=\"displayMode\"\n :reverse-order=\"reverseOrder\"\n :no-padding=\"noPadding\"\n :background-color=\"backgroundColor\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { t } from '@/i18n'\nimport type { TopbarBadge as TopbarBadgeType } from '@/types/comfy'\n\nimport TopbarBadge from './TopbarBadge.vue'\n\nwithDefaults(\n defineProps<{\n displayMode?: 'full' | 'compact' | 'icon-only'\n reverseOrder?: boolean\n noPadding?: boolean\n backgroundColor?: string\n }>(),\n {\n displayMode: 'full',\n reverseOrder: false,\n noPadding: false,\n backgroundColor: 'var(--comfy-menu-bg)'\n }\n)\n\nconst cloudBadge = computed<TopbarBadgeType>(() => ({\n label: t('g.beta'),\n text: 'Comfy Cloud'\n}))\n</script>\n","<template>\n <TopbarBadge\n :badge=\"cloudBadge\"\n :display-mode=\"displayMode\"\n :reverse-order=\"reverseOrder\"\n :no-padding=\"noPadding\"\n :background-color=\"backgroundColor\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { t } from '@/i18n'\nimport type { TopbarBadge as TopbarBadgeType } from '@/types/comfy'\n\nimport TopbarBadge from './TopbarBadge.vue'\n\nwithDefaults(\n defineProps<{\n displayMode?: 'full' | 'compact' | 'icon-only'\n reverseOrder?: boolean\n noPadding?: boolean\n backgroundColor?: string\n }>(),\n {\n displayMode: 'full',\n reverseOrder: false,\n noPadding: false,\n backgroundColor: 'var(--comfy-menu-bg)'\n }\n)\n\nconst cloudBadge = computed<TopbarBadgeType>(() => ({\n label: t('g.beta'),\n text: 'Comfy Cloud'\n}))\n</script>\n"],"mappings":"kWCiCA,MAAM,EAAa,EAAA,KAAiC,CAClD,MAAO,EAAE,QAAA,EACT,KAAM,eACP"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var V=Object.defineProperty;var u=(p,e)=>V(p,"name",{value:e,configurable:!0});import{it as k,ut as C}from"./vendor-primevue-DcMRXJN3.js";import{$o as t,Ba as a,Do as c,Ha as w,Jo as o,Ka as n,Ma as R,Ua as h,Va as B,Ya as M,do as m,qa as _,zo as d}from"./vendor-other-DlQF6V2E.js";import{c as L,n as N}from"./vendor-vue-D9IUuwPJ.js";import"./api-
|
|
1
|
+
var V=Object.defineProperty;var u=(p,e)=>V(p,"name",{value:e,configurable:!0});import{it as k,ut as C}from"./vendor-primevue-DcMRXJN3.js";import{$o as t,Ba as a,Do as c,Ha as w,Jo as o,Ka as n,Ma as R,Ua as h,Va as B,Ya as M,do as m,qa as _,zo as d}from"./vendor-other-DlQF6V2E.js";import{c as L,n as N}from"./vendor-vue-D9IUuwPJ.js";import"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import{t as x}from"./Button-Do2I1OAA.js";import"./PanelTemplate-BJda9e5J.js";import{Mr as S}from"./dialogService-YG0RH337.js";import{t as T}from"./_plugin-vue_export-helper-PHE0iSCb.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BAS9m9W6.js";var q={class:"flex h-full items-center justify-center p-8"},A={class:"max-w-[100vw] p-2 lg:w-96"},E={class:"mb-8 flex flex-col gap-4"},D={class:"my-0 text-xl leading-normal font-medium"},I={class:"my-0 text-base text-muted"},U={class:"flex flex-col gap-2"},$={class:"mb-2 text-base font-medium opacity-80",for:"reset-email"},j={key:0,class:"text-red-500"},z={class:"flex flex-col gap-4"},H={class:"mt-5 text-sm text-gray-600"},J=M({__name:"CloudForgotPasswordView",setup(p){const{t:e}=N(),y=L(),P=S(),s=d(""),l=d(!1),r=d(""),i=d(""),v=u(()=>{y.push({name:"cloud-login"})},"navigateToLogin"),b=u(async()=>{if(!s.value){r.value=e("cloudForgotPassword_emailRequired");return}l.value=!0,r.value="",i.value="";try{await P.sendPasswordReset(s.value),i.value=e("cloudForgotPassword_passwordResetSent"),setTimeout(()=>{v()},3e3)}catch(f){console.error("Password reset error:",f),r.value=e("cloudForgotPassword_passwordResetError")}finally{l.value=!1}},"handleSubmit");return(f,g)=>(m(),h("div",q,[a("div",A,[a("div",E,[a("h1",D,t(o(e)("cloudForgotPassword_title")),1),a("p",I,t(o(e)("cloudForgotPassword_instructions")),1)]),a("form",{class:"flex flex-col gap-6",onSubmit:R(b,["prevent"])},[a("div",U,[a("label",$,t(o(e)("cloudForgotPassword_emailLabel")),1),_(o(k),{id:"reset-email",modelValue:s.value,"onUpdate:modelValue":g[0]||(g[0]=F=>s.value=F),type:"email",placeholder:o(e)("cloudForgotPassword_emailPlaceholder"),class:"h-10",invalid:!!r.value&&!s.value,autocomplete:"email",required:""},null,8,["modelValue","placeholder","invalid"]),r.value?(m(),h("small",j,t(r.value),1)):w("",!0)]),i.value?(m(),B(o(C),{key:0,severity:"success"},{default:c(()=>[n(t(i.value),1)]),_:1})):w("",!0),a("div",z,[_(x,{type:"submit",loading:l.value,disabled:!s.value||l.value,class:"h-10 font-medium text-white"},{default:c(()=>[n(t(o(e)("cloudForgotPassword_sendResetLink")),1)]),_:1},8,["loading","disabled"]),_(x,{type:"button",variant:"secondary",class:"h-10 bg-[#2d2e32]",onClick:v},{default:c(()=>[n(t(o(e)("cloudForgotPassword_backToLogin")),1)]),_:1})])],32),a("p",H,t(o(e)("cloudForgotPassword_didntReceiveEmail")),1)])]))}}),ue=T(J,[["__scopeId","data-v-127dc072"]]);export{ue as default};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=CloudForgotPasswordView-
|
|
3
|
+
//# sourceMappingURL=CloudForgotPasswordView-DOEV9hGr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudForgotPasswordView-
|
|
1
|
+
{"version":3,"file":"CloudForgotPasswordView-DOEV9hGr.js","names":[],"sources":["../../src/platform/cloud/onboarding/CloudForgotPasswordView.vue","../../src/platform/cloud/onboarding/CloudForgotPasswordView.vue"],"sourcesContent":["<template>\n <div class=\"flex h-full items-center justify-center p-8\">\n <div class=\"max-w-[100vw] p-2 lg:w-96\">\n <!-- Header -->\n <div class=\"mb-8 flex flex-col gap-4\">\n <h1 class=\"my-0 text-xl leading-normal font-medium\">\n {{ t('cloudForgotPassword_title') }}\n </h1>\n <p class=\"my-0 text-base text-muted\">\n {{ t('cloudForgotPassword_instructions') }}\n </p>\n </div>\n\n <!-- Form -->\n <form class=\"flex flex-col gap-6\" @submit.prevent=\"handleSubmit\">\n <div class=\"flex flex-col gap-2\">\n <label\n class=\"mb-2 text-base font-medium opacity-80\"\n for=\"reset-email\"\n >\n {{ t('cloudForgotPassword_emailLabel') }}\n </label>\n <InputText\n id=\"reset-email\"\n v-model=\"email\"\n type=\"email\"\n :placeholder=\"t('cloudForgotPassword_emailPlaceholder')\"\n class=\"h-10\"\n :invalid=\"!!errorMessage && !email\"\n autocomplete=\"email\"\n required\n />\n <small v-if=\"errorMessage\" class=\"text-red-500\">\n {{ errorMessage }}\n </small>\n </div>\n\n <Message v-if=\"successMessage\" severity=\"success\">\n {{ successMessage }}\n </Message>\n\n <div class=\"flex flex-col gap-4\">\n <Button\n type=\"submit\"\n :loading=\"loading\"\n :disabled=\"!email || loading\"\n class=\"h-10 font-medium text-white\"\n >\n {{ t('cloudForgotPassword_sendResetLink') }}\n </Button>\n\n <Button\n type=\"button\"\n variant=\"secondary\"\n class=\"h-10 bg-[#2d2e32]\"\n @click=\"navigateToLogin\"\n >\n {{ t('cloudForgotPassword_backToLogin') }}\n </Button>\n </div>\n </form>\n\n <!-- Help text -->\n <p class=\"mt-5 text-sm text-gray-600\">\n {{ t('cloudForgotPassword_didntReceiveEmail') }}\n </p>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport InputText from 'primevue/inputtext'\nimport Message from 'primevue/message'\nimport { ref } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { useRouter } from 'vue-router'\n\nimport Button from '@/components/ui/button/Button.vue'\nimport { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst authActions = useFirebaseAuthActions()\n\nconst email = ref('')\nconst loading = ref(false)\nconst errorMessage = ref('')\nconst successMessage = ref('')\n\nconst navigateToLogin = () => {\n void router.push({ name: 'cloud-login' })\n}\n\nconst handleSubmit = async () => {\n if (!email.value) {\n errorMessage.value = t('cloudForgotPassword_emailRequired')\n return\n }\n\n loading.value = true\n errorMessage.value = ''\n successMessage.value = ''\n\n try {\n // sendPasswordReset is already wrapped and returns a promise\n await authActions.sendPasswordReset(email.value)\n\n successMessage.value = t('cloudForgotPassword_passwordResetSent')\n\n // Optionally redirect to login after a delay\n setTimeout(() => {\n navigateToLogin()\n }, 3000)\n } catch (error) {\n console.error('Password reset error:', error)\n errorMessage.value = t('cloudForgotPassword_passwordResetError')\n } finally {\n loading.value = false\n }\n}\n</script>\n<style scoped>\n:deep(.p-inputtext) {\n border: none !important;\n box-shadow: none !important;\n background: #2d2e32 !important;\n}\n</style>\n","<template>\n <div class=\"flex h-full items-center justify-center p-8\">\n <div class=\"max-w-[100vw] p-2 lg:w-96\">\n <!-- Header -->\n <div class=\"mb-8 flex flex-col gap-4\">\n <h1 class=\"my-0 text-xl leading-normal font-medium\">\n {{ t('cloudForgotPassword_title') }}\n </h1>\n <p class=\"my-0 text-base text-muted\">\n {{ t('cloudForgotPassword_instructions') }}\n </p>\n </div>\n\n <!-- Form -->\n <form class=\"flex flex-col gap-6\" @submit.prevent=\"handleSubmit\">\n <div class=\"flex flex-col gap-2\">\n <label\n class=\"mb-2 text-base font-medium opacity-80\"\n for=\"reset-email\"\n >\n {{ t('cloudForgotPassword_emailLabel') }}\n </label>\n <InputText\n id=\"reset-email\"\n v-model=\"email\"\n type=\"email\"\n :placeholder=\"t('cloudForgotPassword_emailPlaceholder')\"\n class=\"h-10\"\n :invalid=\"!!errorMessage && !email\"\n autocomplete=\"email\"\n required\n />\n <small v-if=\"errorMessage\" class=\"text-red-500\">\n {{ errorMessage }}\n </small>\n </div>\n\n <Message v-if=\"successMessage\" severity=\"success\">\n {{ successMessage }}\n </Message>\n\n <div class=\"flex flex-col gap-4\">\n <Button\n type=\"submit\"\n :loading=\"loading\"\n :disabled=\"!email || loading\"\n class=\"h-10 font-medium text-white\"\n >\n {{ t('cloudForgotPassword_sendResetLink') }}\n </Button>\n\n <Button\n type=\"button\"\n variant=\"secondary\"\n class=\"h-10 bg-[#2d2e32]\"\n @click=\"navigateToLogin\"\n >\n {{ t('cloudForgotPassword_backToLogin') }}\n </Button>\n </div>\n </form>\n\n <!-- Help text -->\n <p class=\"mt-5 text-sm text-gray-600\">\n {{ t('cloudForgotPassword_didntReceiveEmail') }}\n </p>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport InputText from 'primevue/inputtext'\nimport Message from 'primevue/message'\nimport { ref } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { useRouter } from 'vue-router'\n\nimport Button from '@/components/ui/button/Button.vue'\nimport { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst authActions = useFirebaseAuthActions()\n\nconst email = ref('')\nconst loading = ref(false)\nconst errorMessage = ref('')\nconst successMessage = ref('')\n\nconst navigateToLogin = () => {\n void router.push({ name: 'cloud-login' })\n}\n\nconst handleSubmit = async () => {\n if (!email.value) {\n errorMessage.value = t('cloudForgotPassword_emailRequired')\n return\n }\n\n loading.value = true\n errorMessage.value = ''\n successMessage.value = ''\n\n try {\n // sendPasswordReset is already wrapped and returns a promise\n await authActions.sendPasswordReset(email.value)\n\n successMessage.value = t('cloudForgotPassword_passwordResetSent')\n\n // Optionally redirect to login after a delay\n setTimeout(() => {\n navigateToLogin()\n }, 3000)\n } catch (error) {\n console.error('Password reset error:', error)\n errorMessage.value = t('cloudForgotPassword_passwordResetError')\n } finally {\n loading.value = false\n }\n}\n</script>\n<style scoped>\n:deep(.p-inputtext) {\n border: none !important;\n box-shadow: none !important;\n background: #2d2e32 !important;\n}\n</style>\n"],"mappings":"2xCCgFA,KAAM,CAAE,EAAA,CAAA,EAAM,EAAA,EACR,EAAS,EAAA,EACT,EAAc,EAAA,EAEd,EAAQ,EAAI,EAAA,EACZ,EAAU,EAAI,EAAA,EACd,EAAe,EAAI,EAAA,EACnB,EAAiB,EAAI,EAAA,EAErB,EAAA,EAAA,IAAwB,CACvB,EAAO,KAAK,CAAE,KAAM,aAAA,CAAe,GADpC,mBAIA,EAAe,EAAA,SAAY,CAC/B,GAAI,CAAC,EAAM,MAAO,CAChB,EAAa,MAAQ,EAAE,mCAAA,EACvB,OAGF,EAAQ,MAAQ,GAChB,EAAa,MAAQ,GACrB,EAAe,MAAQ,GAEvB,GAAI,CAEF,MAAM,EAAY,kBAAkB,EAAM,KAAA,EAE1C,EAAe,MAAQ,EAAE,uCAAA,EAGzB,WAAA,IAAiB,CACf,EAAA,GACC,GAAA,QACI,EAAO,CACd,QAAQ,MAAM,wBAAyB,CAAA,EACvC,EAAa,MAAQ,EAAE,wCAAA,UAEvB,EAAQ,MAAQ,KAxBC"}
|
comfyui_frontend_package/static/assets/{CloudLayoutView-vTrrVUOY.js → CloudLayoutView-ShKH6rRV.js}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var m=Object.defineProperty;var p=(l,a)=>m(l,"name",{value:a,configurable:!0});import"./vendor-primevue-DcMRXJN3.js";import{$o as o,Ba as e,Do as i,Jo as t,Ka as f,Pa as v,Ua as u,Ya as c,do as _,mo as h,qa as r}from"./vendor-other-DlQF6V2E.js";import{n as x,r as w}from"./vendor-vue-D9IUuwPJ.js";import{A as s}from"./api-
|
|
1
|
+
var m=Object.defineProperty;var p=(l,a)=>m(l,"name",{value:a,configurable:!0});import"./vendor-primevue-DcMRXJN3.js";import{$o as o,Ba as e,Do as i,Jo as t,Ka as f,Pa as v,Ua as u,Ya as c,do as _,mo as h,qa as r}from"./vendor-other-DlQF6V2E.js";import{n as x,r as w}from"./vendor-vue-D9IUuwPJ.js";import{A as s}from"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import{t as g}from"./Button-Do2I1OAA.js";import"./PanelTemplate-BJda9e5J.js";import"./dialogService-YG0RH337.js";import{t as y}from"./_plugin-vue_export-helper-PHE0iSCb.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BAS9m9W6.js";import{t as b}from"./GlobalToast-BSCvu6Hw.js";import{t as k}from"./BaseViewTemplate-CjODF2hh.js";var C=""+new URL("thumbnail-imMA3y7Z.png",import.meta.url).href,L=""+new URL("video-BvOHf4P9.mp4",import.meta.url).href,T=""+new URL("images/comfy-cloud-logo.svg",import.meta.url).href,$={},V={class:"mx-auto flex h-[7%] max-h-[70px] w-5/6 items-end"},B=["alt"];function S(l,a){return _(),u("div",V,[e("img",{src:T,alt:l.$t("subscription.comfyCloudLogo"),class:"h-3/4 max-h-10 w-auto"},null,8,B)])}p(S,"_sfc_render");var F=y($,[["render",S]]),R={class:"mx-auto flex h-[5%] max-h-[60px] w-5/6 items-start gap-2.5"},j={href:"https://www.comfy.org/terms-of-service",target:"_blank",class:"cursor-pointer text-sm text-gray-600 no-underline"},U={href:"https://www.comfy.org/privacy-policy",target:"_blank",class:"cursor-pointer text-sm text-gray-600 no-underline"},D={href:"https://support.comfy.org",class:"cursor-pointer text-sm text-gray-600 no-underline",target:"_blank",rel:"noopener noreferrer"},N=c({__name:"CloudTemplateFooter",setup(l){const{t:a}=x();return(n,d)=>(_(),u("footer",R,[e("a",j,o(t(a)("auth.login.termsLink")),1),e("a",U,o(t(a)("auth.login.privacyLink")),1),e("a",D,o(t(a)("cloudFooter_needHelp")),1)]))}}),A=N,H={class:"flex"},P={class:"relative hidden flex-1 overflow-hidden bg-black lg:block"},q=["poster"],E=["src"],G={class:"absolute inset-0 flex items-center justify-center text-center text-white"},I={class:"font-abcrom hero-title font-black uppercase italic"},J={class:"m-2 text-center text-xl text-white"},K={class:"m-0 text-center text-xl text-white"},M={class:"absolute inset-0 flex flex-col justify-end px-14 pb-[64px]"},O={class:"flex items-center justify-end"},Y={class:"flex items-center gap-3"},Z={class:"text-md text-white"},z=c({__name:"CloudTemplate",setup(l){const a=p(()=>{window.open("https://www.comfy.org/download","_blank")},"handleDownloadClick");return(n,d)=>(_(),u("div",H,[r(k,{dark:"",class:"flex-1"},{header:i(()=>[r(F)]),footer:i(()=>[r(A)]),default:i(()=>[h(n.$slots,"default")]),_:3}),e("div",P,[e("video",{class:"absolute inset-0 h-full w-full object-cover",autoplay:"",muted:"",loop:"",playsinline:"",poster:t(C)},[e("source",{src:t(L),type:"video/mp4"},null,8,E)],8,q),d[0]||(d[0]=e("div",{class:"absolute inset-0 h-full w-full bg-black/30"},null,-1)),e("div",G,[e("div",null,[e("h1",I,o(t(s)("cloudStart_title")),1),e("p",J,o(t(s)("cloudStart_desc")),1),e("p",K,o(t(s)("cloudStart_explain")),1)])]),e("div",M,[e("div",O,[e("div",Y,[e("p",Z,o(t(s)("cloudStart_wantToRun")),1),r(g,{type:"button",class:"h-10 bg-black font-bold text-white",variant:"secondary",onClick:a},{default:i(()=>[f(o(t(s)("cloudStart_download")),1)]),_:1})])])])])]))}}),Q=z,W=c({__name:"CloudLayoutView",setup(l){return(a,n)=>(_(),u(v,null,[r(Q,null,{default:i(()=>[r(t(w))]),_:1}),r(b)],64))}}),xe=W;export{xe as default};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=CloudLayoutView-
|
|
3
|
+
//# sourceMappingURL=CloudLayoutView-ShKH6rRV.js.map
|