From a292741ff49f6c51caa169feb20926be2e7f1cf9 Mon Sep 17 00:00:00 2001 From: Crystian Date: Tue, 30 Jul 2024 16:55:50 +0200 Subject: [PATCH 01/31] vertical behavior extracted to own class --- web/progressBar.js | 85 +++---------------- web/progressBar.ts | 94 +++------------------ web/progressBarVertical.d.ts | 16 ++++ web/progressBarVertical.js | 157 +++++++++++++++++++++++++++++++++++ web/progressBarVertical.ts | 118 ++++++++++++++++++++++++++ web/types.d.ts | 5 ++ web/types.js | 6 ++ web/types.ts | 5 ++ 8 files changed, 330 insertions(+), 156 deletions(-) create mode 100644 web/progressBarVertical.d.ts create mode 100644 web/progressBarVertical.js create mode 100644 web/progressBarVertical.ts create mode 100644 web/types.d.ts create mode 100644 web/types.js create mode 100644 web/types.ts diff --git a/web/progressBar.js b/web/progressBar.js index 7cdcd9a..43cde9b 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -1,12 +1,8 @@ import { api } from '/scripts/api.js'; import { app } from '/scripts/app.js'; import { commonPrefix } from './common.js'; -var EStatus; -(function (EStatus) { - EStatus["executing"] = "Executing"; - EStatus["executed"] = "Executed"; - EStatus["execution_error"] = "Execution error"; -})(EStatus || (EStatus = {})); +import { EStatus } from './types.js'; +import { ProgressBarVertical } from './progressBarVertical.js'; class CrystoolsProgressBar { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -81,6 +77,12 @@ class CrystoolsProgressBar { writable: true, value: undefined }); + Object.defineProperty(this, "progressBarVertical", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); Object.defineProperty(this, "createSettings", { enumerable: true, configurable: true, @@ -111,27 +113,7 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: () => { - if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { - console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); - return; - } - if (this.currentStatus === EStatus.executed) { - this.htmlProgressLabelRef.innerHTML = 'cached'; - const timeElapsed = Date.now() - this.timeStart; - if (this.timeStart > 0 && timeElapsed > 0) { - this.htmlProgressLabelRef.innerHTML = new Date(timeElapsed).toISOString().substr(11, 8); - } - this.htmlProgressSliderRef.style.width = '0'; - } - else if (this.currentStatus === EStatus.execution_error) { - this.htmlProgressLabelRef.innerHTML = 'ERROR'; - this.htmlProgressSliderRef.style.backgroundColor = 'var(--error-text)'; - } - else if (this.currentStatus === EStatus.executing) { - this.htmlProgressLabelRef.innerHTML = `${this.currentProgress}%`; - this.htmlProgressSliderRef.style.width = this.htmlProgressLabelRef.innerHTML; - this.htmlProgressSliderRef.style.backgroundColor = 'green'; - } + this.progressBarVertical.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } }); Object.defineProperty(this, "registerListeners", { @@ -192,52 +174,9 @@ class CrystoolsProgressBar { this.createSettings(); } setup() { - const parentElement = document.getElementById('queue-button'); - if (!parentElement) { - console.error('queue-button not found'); - return; - } - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - parentElement.insertAdjacentElement('afterend', ctoolsRoot); - } - const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); - htmlContainer.setAttribute('title', 'click to see the current working node'); - htmlContainer.style.margin = '4px 0'; - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'pointer'; - htmlContainer.style.order = '1'; - htmlContainer.addEventListener('click', this.centerNode); - ctoolsRoot.append(htmlContainer); - const progressBar = document.createElement('div'); - progressBar.style.margin = '0 10px'; - progressBar.style.height = '18px'; - progressBar.style.position = 'relative'; - progressBar.style.backgroundColor = 'var(--bg-color)'; - htmlContainer.append(progressBar); - const progressSlider = document.createElement('div'); - progressSlider.style.position = 'absolute'; - progressSlider.style.height = '100%'; - progressSlider.style.width = '0'; - progressSlider.style.transition = 'width 0.2s'; - progressSlider.style.backgroundColor = 'green'; - this.htmlProgressSliderRef = progressSlider; - progressBar.append(this.htmlProgressSliderRef); - const progressLabel = document.createElement('div'); - progressLabel.style.position = 'absolute'; - progressLabel.style.margin = 'auto 0'; - progressLabel.style.width = '100%'; - progressLabel.style.color = 'var(--drag-text)'; - progressLabel.style.fontSize = '14px'; - progressLabel.innerHTML = '0%'; - this.htmlProgressLabelRef = progressLabel; - progressBar.append(this.htmlProgressLabelRef); + this.progressBarVertical = new ProgressBarVertical(this.htmlIdCrystoolsRoot, this.htmlIdCrystoolsProgressBarContainer, this.centerNode); + this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; + this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); this.registerListeners(); } diff --git a/web/progressBar.ts b/web/progressBar.ts index 4fe5e1e..f681eb2 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -1,12 +1,8 @@ import { api } from '/scripts/api.js'; import { app } from '/scripts/app.js'; import { commonPrefix } from './common.js'; - -enum EStatus { - executing = 'Executing', - executed = 'Executed', - execution_error = 'Execution error', -} +import { EStatus } from './types.js'; +import { ProgressBarVertical } from './progressBarVertical.js'; class CrystoolsProgressBar { idExtensionName = 'Crystools.progressBar'; @@ -24,6 +20,8 @@ class CrystoolsProgressBar { htmlProgressSliderRef?: HTMLDivElement = undefined; htmlProgressLabelRef?: HTMLDivElement = undefined; + progressBarVertical: ProgressBarVertical; + constructor() { this.createSettings(); } @@ -49,86 +47,16 @@ class CrystoolsProgressBar { }; updateDisplay = (): void => { - if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { - console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); - return; - } - - if (this.currentStatus === EStatus.executed) { - // finished - this.htmlProgressLabelRef.innerHTML = 'cached'; - - const timeElapsed = Date.now() - this.timeStart; - if (this.timeStart > 0 && timeElapsed > 0) { - this.htmlProgressLabelRef.innerHTML = new Date(timeElapsed).toISOString().substr(11, 8); - } - this.htmlProgressSliderRef.style.width = '0'; - - } else if (this.currentStatus === EStatus.execution_error) { - // an error occurred - this.htmlProgressLabelRef.innerHTML = 'ERROR'; - this.htmlProgressSliderRef.style.backgroundColor = 'var(--error-text)'; - - } else if (this.currentStatus === EStatus.executing) { - // on going - this.htmlProgressLabelRef.innerHTML = `${this.currentProgress}%`; - this.htmlProgressSliderRef.style.width = this.htmlProgressLabelRef.innerHTML; - this.htmlProgressSliderRef.style.backgroundColor = 'green'; // by reset the color - } + this.progressBarVertical.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); }; setup(): void { - const parentElement = document.getElementById('queue-button'); - if (!parentElement) { - console.error('queue-button not found'); - return; - } - - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - parentElement.insertAdjacentElement('afterend', ctoolsRoot); - } - - const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); - htmlContainer.setAttribute('title', 'click to see the current working node'); - htmlContainer.style.margin = '4px 0'; - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'pointer'; - htmlContainer.style.order = '1'; - htmlContainer.addEventListener('click', this.centerNode); - ctoolsRoot.append(htmlContainer); - - const progressBar = document.createElement('div'); - progressBar.style.margin = '0 10px'; - progressBar.style.height = '18px'; - progressBar.style.position = 'relative'; - progressBar.style.backgroundColor = 'var(--bg-color)'; - htmlContainer.append(progressBar); - - const progressSlider = document.createElement('div'); - progressSlider.style.position = 'absolute'; - progressSlider.style.height = '100%'; - progressSlider.style.width = '0'; - progressSlider.style.transition = 'width 0.2s'; - progressSlider.style.backgroundColor = 'green'; - this.htmlProgressSliderRef = progressSlider; - progressBar.append(this.htmlProgressSliderRef); - - const progressLabel = document.createElement('div'); - progressLabel.style.position = 'absolute'; - progressLabel.style.margin = 'auto 0'; - progressLabel.style.width = '100%'; - progressLabel.style.color = 'var(--drag-text)'; - progressLabel.style.fontSize = '14px'; - progressLabel.innerHTML = '0%'; - this.htmlProgressLabelRef = progressLabel; - progressBar.append(this.htmlProgressLabelRef); + this.progressBarVertical = new ProgressBarVertical( + this.htmlIdCrystoolsRoot, + this.htmlIdCrystoolsProgressBarContainer, + this.centerNode); + this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; + this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); this.registerListeners(); diff --git a/web/progressBarVertical.d.ts b/web/progressBarVertical.d.ts new file mode 100644 index 0000000..50cafc4 --- /dev/null +++ b/web/progressBarVertical.d.ts @@ -0,0 +1,16 @@ +import { EStatus } from './types.js'; +export declare class ProgressBarVertical { + htmlIdCrystoolsRoot: string; + htmlIdCrystoolsProgressBarContainer: string; + private centerNode; + htmlProgressSliderRef: HTMLDivElement; + htmlProgressLabelRef: HTMLDivElement; + queueButtonElement: HTMLElement | null; + currentStatus: EStatus; + timeStart: number; + currentProgress: number; + constructor(htmlIdCrystoolsRoot: string, htmlIdCrystoolsProgressBarContainer: string, centerNode: () => void); + createVertical: () => void; + refreshDisplay: () => void; + updateDisplay: (currentStatus: EStatus, timeStart: number, currentProgress: number) => void; +} diff --git a/web/progressBarVertical.js b/web/progressBarVertical.js new file mode 100644 index 0000000..74af537 --- /dev/null +++ b/web/progressBarVertical.js @@ -0,0 +1,157 @@ +import { app } from '/scripts/app.js'; +import { EStatus } from './types.js'; +export class ProgressBarVertical { + constructor(htmlIdCrystoolsRoot, htmlIdCrystoolsProgressBarContainer, centerNode) { + Object.defineProperty(this, "htmlIdCrystoolsRoot", { + enumerable: true, + configurable: true, + writable: true, + value: htmlIdCrystoolsRoot + }); + Object.defineProperty(this, "htmlIdCrystoolsProgressBarContainer", { + enumerable: true, + configurable: true, + writable: true, + value: htmlIdCrystoolsProgressBarContainer + }); + Object.defineProperty(this, "centerNode", { + enumerable: true, + configurable: true, + writable: true, + value: centerNode + }); + Object.defineProperty(this, "htmlProgressSliderRef", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "htmlProgressLabelRef", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "queueButtonElement", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "currentStatus", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "timeStart", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "currentProgress", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "createVertical", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); + if (!ctoolsRoot) { + ctoolsRoot = document.createElement('div'); + ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); + ctoolsRoot.style.display = 'flex'; + ctoolsRoot.style.width = '100%'; + ctoolsRoot.style.flexDirection = 'column'; + this.queueButtonElement?.insertAdjacentElement('afterend', ctoolsRoot); + } + const htmlContainer = document.createElement('div'); + htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); + htmlContainer.setAttribute('title', 'click to see the current working node'); + htmlContainer.style.margin = '4px 0'; + htmlContainer.style.width = '100%'; + htmlContainer.style.cursor = 'pointer'; + htmlContainer.style.order = '1'; + htmlContainer.addEventListener('click', this.centerNode); + ctoolsRoot.append(htmlContainer); + const progressBar = document.createElement('div'); + progressBar.style.margin = '0 10px'; + progressBar.style.height = '18px'; + progressBar.style.position = 'relative'; + progressBar.style.backgroundColor = 'var(--bg-color)'; + htmlContainer.append(progressBar); + const progressSlider = document.createElement('div'); + progressSlider.style.position = 'absolute'; + progressSlider.style.height = '100%'; + progressSlider.style.width = '0'; + progressSlider.style.transition = 'width 0.2s'; + progressSlider.style.backgroundColor = 'green'; + this.htmlProgressSliderRef = progressSlider; + progressBar.append(this.htmlProgressSliderRef); + const progressLabel = document.createElement('div'); + progressLabel.style.position = 'absolute'; + progressLabel.style.margin = 'auto 0'; + progressLabel.style.width = '100%'; + progressLabel.style.color = 'var(--drag-text)'; + progressLabel.style.fontSize = '14px'; + progressLabel.innerHTML = '0%'; + this.htmlProgressLabelRef = progressLabel; + progressBar.append(this.htmlProgressLabelRef); + } + }); + Object.defineProperty(this, "refreshDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + } + }); + Object.defineProperty(this, "updateDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: (currentStatus, timeStart, currentProgress) => { + if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { + console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); + return; + } + this.currentStatus = currentStatus; + this.timeStart = timeStart; + this.currentProgress = currentProgress; + const menu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + console.log('menu', menu); + if (currentStatus === EStatus.executed) { + this.htmlProgressLabelRef.innerHTML = 'cached'; + const timeElapsed = Date.now() - timeStart; + if (timeStart > 0 && timeElapsed > 0) { + this.htmlProgressLabelRef.innerHTML = new Date(timeElapsed).toISOString().substr(11, 8); + } + this.htmlProgressSliderRef.style.width = '0'; + } + else if (currentStatus === EStatus.execution_error) { + this.htmlProgressLabelRef.innerHTML = 'ERROR'; + this.htmlProgressSliderRef.style.backgroundColor = 'var(--error-text)'; + } + else if (currentStatus === EStatus.executing) { + this.htmlProgressLabelRef.innerHTML = `${currentProgress}%`; + this.htmlProgressSliderRef.style.width = this.htmlProgressLabelRef.innerHTML; + this.htmlProgressSliderRef.style.backgroundColor = 'green'; + } + } + }); + this.htmlIdCrystoolsRoot = htmlIdCrystoolsRoot; + this.htmlIdCrystoolsProgressBarContainer = htmlIdCrystoolsProgressBarContainer; + this.queueButtonElement = document.getElementById('queue-button'); + if (!this.queueButtonElement) { + throw new Error('queue-button not found'); + } + this.createVertical(); + window.addEventListener('resize', this.refreshDisplay); + } +} diff --git a/web/progressBarVertical.ts b/web/progressBarVertical.ts new file mode 100644 index 0000000..4283f6c --- /dev/null +++ b/web/progressBarVertical.ts @@ -0,0 +1,118 @@ +import { app } from '/scripts/app.js'; +import { EStatus } from './types.js'; + +export class ProgressBarVertical { + htmlProgressSliderRef: HTMLDivElement; + htmlProgressLabelRef: HTMLDivElement; + queueButtonElement: HTMLElement | null; + currentStatus: EStatus; + timeStart: number; + currentProgress: number; + + constructor( + public htmlIdCrystoolsRoot: string, + public htmlIdCrystoolsProgressBarContainer: string, + private centerNode: () => void + ) { + this.htmlIdCrystoolsRoot = htmlIdCrystoolsRoot; + this.htmlIdCrystoolsProgressBarContainer = htmlIdCrystoolsProgressBarContainer; + this.queueButtonElement = document.getElementById('queue-button'); + if (!this.queueButtonElement) { + throw new Error('queue-button not found'); + } + + this.createVertical(); + + window.addEventListener('resize', this.refreshDisplay); + } + + createVertical = (): void => { + let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); + if (!ctoolsRoot) { + ctoolsRoot = document.createElement('div'); + ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); + ctoolsRoot.style.display = 'flex'; + ctoolsRoot.style.width = '100%'; + ctoolsRoot.style.flexDirection = 'column'; + this.queueButtonElement?.insertAdjacentElement('afterend', ctoolsRoot); + } + + const htmlContainer = document.createElement('div'); + htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); + htmlContainer.setAttribute('title', 'click to see the current working node'); + htmlContainer.style.margin = '4px 0'; + htmlContainer.style.width = '100%'; + htmlContainer.style.cursor = 'pointer'; + htmlContainer.style.order = '1'; + htmlContainer.addEventListener('click', this.centerNode); + ctoolsRoot.append(htmlContainer); + + const progressBar = document.createElement('div'); + progressBar.style.margin = '0 10px'; + progressBar.style.height = '18px'; + progressBar.style.position = 'relative'; + progressBar.style.backgroundColor = 'var(--bg-color)'; + htmlContainer.append(progressBar); + + const progressSlider = document.createElement('div'); + progressSlider.style.position = 'absolute'; + progressSlider.style.height = '100%'; + progressSlider.style.width = '0'; + progressSlider.style.transition = 'width 0.2s'; + progressSlider.style.backgroundColor = 'green'; + this.htmlProgressSliderRef = progressSlider; + progressBar.append(this.htmlProgressSliderRef); + + const progressLabel = document.createElement('div'); + progressLabel.style.position = 'absolute'; + progressLabel.style.margin = 'auto 0'; + progressLabel.style.width = '100%'; + progressLabel.style.color = 'var(--drag-text)'; + progressLabel.style.fontSize = '14px'; + progressLabel.innerHTML = '0%'; + this.htmlProgressLabelRef = progressLabel; + progressBar.append(this.htmlProgressLabelRef); + }; + + refreshDisplay = (): void => { + this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + }; + + updateDisplay = (currentStatus: EStatus, timeStart: number, currentProgress: number): void => { + if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { + console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); + return; + } + + this.currentStatus = currentStatus; + this.timeStart = timeStart; + this.currentProgress = currentProgress; + + const menu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + console.log('menu', menu); + + if (currentStatus === EStatus.executed) { + // finished + this.htmlProgressLabelRef.innerHTML = 'cached'; + + const timeElapsed = Date.now() - timeStart; + if (timeStart > 0 && timeElapsed > 0) { + this.htmlProgressLabelRef.innerHTML = new Date(timeElapsed).toISOString().substr(11, 8); + } + this.htmlProgressSliderRef.style.width = '0'; + + } else if (currentStatus === EStatus.execution_error) { + // an error occurred + this.htmlProgressLabelRef.innerHTML = 'ERROR'; + this.htmlProgressSliderRef.style.backgroundColor = 'var(--error-text)'; + + } else if (currentStatus === EStatus.executing) { + // on going + this.htmlProgressLabelRef.innerHTML = `${currentProgress}%`; + this.htmlProgressSliderRef.style.width = this.htmlProgressLabelRef.innerHTML; + this.htmlProgressSliderRef.style.backgroundColor = 'green'; // by reset the color + } + + }; + +} diff --git a/web/types.d.ts b/web/types.d.ts new file mode 100644 index 0000000..7682c24 --- /dev/null +++ b/web/types.d.ts @@ -0,0 +1,5 @@ +export declare enum EStatus { + executing = "Executing", + executed = "Executed", + execution_error = "Execution error" +} diff --git a/web/types.js b/web/types.js new file mode 100644 index 0000000..acfb065 --- /dev/null +++ b/web/types.js @@ -0,0 +1,6 @@ +export var EStatus; +(function (EStatus) { + EStatus["executing"] = "Executing"; + EStatus["executed"] = "Executed"; + EStatus["execution_error"] = "Execution error"; +})(EStatus || (EStatus = {})); diff --git a/web/types.ts b/web/types.ts new file mode 100644 index 0000000..e963d9b --- /dev/null +++ b/web/types.ts @@ -0,0 +1,5 @@ +export enum EStatus { + executing = 'Executing', + executed = 'Executed', + execution_error = 'Execution error', +} From ed77c70ffba5a985f3f2490faa0959c03603b7ae Mon Sep 17 00:00:00 2001 From: Crystian Date: Tue, 30 Jul 2024 17:03:19 +0200 Subject: [PATCH 02/31] vertical behavior extracted to own class --- web/monitorUI.js | 2 ++ web/progressBar.js | 4 ++-- web/progressBar.ts | 6 +++--- web/{progressBarVertical.d.ts => progressBarUI.d.ts} | 2 +- web/{progressBarVertical.js => progressBarUI.js} | 2 +- web/{progressBarVertical.ts => progressBarUI.ts} | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 web/monitorUI.js rename web/{progressBarVertical.d.ts => progressBarUI.d.ts} (93%) rename web/{progressBarVertical.js => progressBarUI.js} (99%) rename web/{progressBarVertical.ts => progressBarUI.ts} (99%) diff --git a/web/monitorUI.js b/web/monitorUI.js new file mode 100644 index 0000000..104a702 --- /dev/null +++ b/web/monitorUI.js @@ -0,0 +1,2 @@ +export class monitorUI { +} diff --git a/web/progressBar.js b/web/progressBar.js index 43cde9b..89d086a 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -1,8 +1,8 @@ import { api } from '/scripts/api.js'; import { app } from '/scripts/app.js'; import { commonPrefix } from './common.js'; +import { ProgressBarUI } from './progressBarUI.js'; import { EStatus } from './types.js'; -import { ProgressBarVertical } from './progressBarVertical.js'; class CrystoolsProgressBar { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -174,7 +174,7 @@ class CrystoolsProgressBar { this.createSettings(); } setup() { - this.progressBarVertical = new ProgressBarVertical(this.htmlIdCrystoolsRoot, this.htmlIdCrystoolsProgressBarContainer, this.centerNode); + this.progressBarVertical = new ProgressBarUI(this.htmlIdCrystoolsRoot, this.htmlIdCrystoolsProgressBarContainer, this.centerNode); this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); diff --git a/web/progressBar.ts b/web/progressBar.ts index f681eb2..044dacb 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -1,8 +1,8 @@ import { api } from '/scripts/api.js'; import { app } from '/scripts/app.js'; import { commonPrefix } from './common.js'; +import { ProgressBarUI } from './progressBarUI.js'; import { EStatus } from './types.js'; -import { ProgressBarVertical } from './progressBarVertical.js'; class CrystoolsProgressBar { idExtensionName = 'Crystools.progressBar'; @@ -20,7 +20,7 @@ class CrystoolsProgressBar { htmlProgressSliderRef?: HTMLDivElement = undefined; htmlProgressLabelRef?: HTMLDivElement = undefined; - progressBarVertical: ProgressBarVertical; + progressBarVertical: ProgressBarUI; constructor() { this.createSettings(); @@ -51,7 +51,7 @@ class CrystoolsProgressBar { }; setup(): void { - this.progressBarVertical = new ProgressBarVertical( + this.progressBarVertical = new ProgressBarUI( this.htmlIdCrystoolsRoot, this.htmlIdCrystoolsProgressBarContainer, this.centerNode); diff --git a/web/progressBarVertical.d.ts b/web/progressBarUI.d.ts similarity index 93% rename from web/progressBarVertical.d.ts rename to web/progressBarUI.d.ts index 50cafc4..694d0ef 100644 --- a/web/progressBarVertical.d.ts +++ b/web/progressBarUI.d.ts @@ -1,5 +1,5 @@ import { EStatus } from './types.js'; -export declare class ProgressBarVertical { +export declare class ProgressBarUI { htmlIdCrystoolsRoot: string; htmlIdCrystoolsProgressBarContainer: string; private centerNode; diff --git a/web/progressBarVertical.js b/web/progressBarUI.js similarity index 99% rename from web/progressBarVertical.js rename to web/progressBarUI.js index 74af537..5655187 100644 --- a/web/progressBarVertical.js +++ b/web/progressBarUI.js @@ -1,6 +1,6 @@ import { app } from '/scripts/app.js'; import { EStatus } from './types.js'; -export class ProgressBarVertical { +export class ProgressBarUI { constructor(htmlIdCrystoolsRoot, htmlIdCrystoolsProgressBarContainer, centerNode) { Object.defineProperty(this, "htmlIdCrystoolsRoot", { enumerable: true, diff --git a/web/progressBarVertical.ts b/web/progressBarUI.ts similarity index 99% rename from web/progressBarVertical.ts rename to web/progressBarUI.ts index 4283f6c..fee50b1 100644 --- a/web/progressBarVertical.ts +++ b/web/progressBarUI.ts @@ -1,7 +1,7 @@ import { app } from '/scripts/app.js'; import { EStatus } from './types.js'; -export class ProgressBarVertical { +export class ProgressBarUI { htmlProgressSliderRef: HTMLDivElement; htmlProgressLabelRef: HTMLDivElement; queueButtonElement: HTMLElement | null; From a34fdeba097da2815a9afb9be9240a8fefed3bb3 Mon Sep 17 00:00:00 2001 From: Crystian Date: Tue, 30 Jul 2024 17:48:39 +0200 Subject: [PATCH 03/31] monitor separated --- web/monitor.js | 237 +++---------------------------------- web/monitor.ts | 253 ++++------------------------------------ web/monitorUI.d.ts | 21 ++++ web/monitorUI.js | 284 ++++++++++++++++++++++++++++++++++++++++++++- web/monitorUI.ts | 247 +++++++++++++++++++++++++++++++++++++++ web/progressBar.ts | 1 + 6 files changed, 588 insertions(+), 455 deletions(-) create mode 100644 web/monitorUI.d.ts create mode 100644 web/monitorUI.ts diff --git a/web/monitor.js b/web/monitor.js index 2d09b49..f8c1d2d 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1,6 +1,7 @@ import { app } from '/scripts/app.js'; import { api } from '/scripts/api.js'; import { commonPrefix } from './common.js'; +import { MonitorUI } from './monitorUI.js'; class CrystoolsMonitor { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -15,17 +16,11 @@ class CrystoolsMonitor { writable: true, value: commonPrefix }); - Object.defineProperty(this, "htmlIdCrystoolsRoot", { + Object.defineProperty(this, "monitorUI", { enumerable: true, configurable: true, writable: true, - value: 'crystools-root' - }); - Object.defineProperty(this, "htmlIdCrystoolsMonitorContainer", { - enumerable: true, - configurable: true, - writable: true, - value: 'crystools-monitor-container' + value: void 0 }); Object.defineProperty(this, "idInputRate", { enumerable: true, @@ -85,7 +80,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#0AA015', onChange: async (value) => { - this.updateWidget(this.monitorCPUElement); + this.monitorUI?.updateWidget(this.monitorCPUElement); await this.updateServer({ switchCPU: value, }); @@ -108,7 +103,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#07630D', onChange: async (value) => { - this.updateWidget(this.monitorRAMElement); + this.monitorUI?.updateWidget(this.monitorRAMElement); await this.updateServer({ switchRAM: value, }); @@ -132,7 +127,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#730F92', onChange: async (value) => { - this.updateWidget(this.monitorHDDElement); + this.monitorUI?.updateWidget(this.monitorHDDElement); await this.updateServer({ switchHDD: value, }); @@ -180,7 +175,7 @@ class CrystoolsMonitor { return; } if (valueNumber === 0) { - this.updateAllMonitors({ + this.monitorUI.updateAllMonitors({ cpu_utilization: 0, device: 'cpu', gpus: [ @@ -200,7 +195,7 @@ class CrystoolsMonitor { ram_used_percent: 0, }); } - this.updateAllAnimationDuration(valueNumber); + this.monitorUI?.updateAllAnimationDuration(valueNumber); }, }); void this.getHDDsFromServer().then((data) => { @@ -253,7 +248,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#0C86F4', onChange: async (value) => { - this.updateWidget(monitorGPUNElement); + this.monitorUI?.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index, { utilization: value }); @@ -272,7 +267,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#176EC7', onChange: async (value) => { - this.updateWidget(monitorVRAMNElement); + this.monitorUI?.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index, { vram: value }); @@ -292,7 +287,7 @@ class CrystoolsMonitor { cssColor: '#00ff00', cssColorFinal: '#ff0000', onChange: async (value) => { - this.updateWidget(monitorTemperatureNElement); + this.monitorUI?.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index, { temperature: value }); @@ -371,185 +366,6 @@ class CrystoolsMonitor { throw new Error(resp.statusText); } }); - Object.defineProperty(this, "updateAllWidget", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - } - }); - Object.defineProperty(this, "updateWidget", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - } - }); - Object.defineProperty(this, "updateAllMonitors", { - enumerable: true, - configurable: true, - writable: true, - value: (data) => { - this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); - if (data.gpus === undefined || data.gpus.length === 0) { - console.warn('UpdateAllMonitors: no GPU data'); - return; - } - this.monitorGPUSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.gpu_utilization); - } - else { - } - }); - this.monitorVRAMSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.vram_used_percent); - } - else { - } - }); - this.monitorTemperatureSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.gpu_temperature); - if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { - monitorSettings.htmlMonitorSliderRef.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; - } - } - else { - } - }); - } - }); - Object.defineProperty(this, "updateMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, percent) => { - if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { - return; - } - monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; - monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; - } - }); - Object.defineProperty(this, "updateAllAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - this.updatedAnimationDuration(this.monitorCPUElement, value); - this.updatedAnimationDuration(this.monitorRAMElement, value); - this.updatedAnimationDuration(this.monitorHDDElement, value); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - } - }); - Object.defineProperty(this, "updatedAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, value) => { - const slider = monitorSettings.htmlMonitorSliderRef; - if (!slider) { - return; - } - slider.style.transition = `width ${value.toFixed(1)}s`; - } - }); - Object.defineProperty(this, "createMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - if (!monitorSettings) { - return document.createElement('div'); - } - const htmlMain = document.createElement('div'); - htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.style.margin = '2px 10px'; - htmlMain.style.height = '12px'; - htmlMain.style.position = 'relative'; - htmlMain.style.display = 'flex'; - htmlMain.style.alignItems = 'center'; - htmlMain.style.flexDirection = 'row'; - monitorSettings.htmlMonitorRef = htmlMain; - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.style.width = '35px'; - htmlMonitorText.style.fontSize = '10px'; - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.style.height = '100%'; - htmlMonitorContent.style.flexGrow = '1'; - htmlMonitorContent.style.position = 'relative'; - htmlMonitorContent.style.backgroundColor = 'var(--bg-color)'; - htmlMain.append(htmlMonitorContent); - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.style.position = 'absolute'; - htmlMonitorSlider.style.height = '100%'; - htmlMonitorSlider.style.width = '0'; - if (monitorSettings.cssColorFinal) { - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } - else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.style.position = 'relative'; - htmlMonitorLabel.style.width = '100%'; - htmlMonitorLabel.style.color = 'var(--drag-text)'; - htmlMonitorLabel.style.fontSize = '10px'; - htmlMonitorLabel.innerHTML = '0%'; - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - return monitorSettings.htmlMonitorRef; - } - }); Object.defineProperty(this, "registerListeners", { enumerable: true, configurable: true, @@ -559,42 +375,15 @@ class CrystoolsMonitor { if (event?.detail === undefined) { return; } - this.updateAllMonitors(event.detail); + this.monitorUI.updateAllMonitors(event.detail); }, false); } }); this.createSettings(); } setup() { - const parentElement = document.getElementById('queue-button'); - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); - } - const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsMonitorContainer); - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'crosshair'; - htmlContainer.style.order = '3'; - htmlContainer.style.margin = '4px 0'; - ctoolsRoot.append(htmlContainer); - htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - htmlContainer.append(this.createMonitor(this.monitorRAMElement)); - this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); - this.monitorTemperatureSettings[index] && - htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); - }); - htmlContainer.append(this.createMonitor(this.monitorHDDElement)); const currentRate = parseFloat(app.ui.settings.getSettingValue(this.idInputRate, this.defaultRate)); - this.updateAllAnimationDuration(currentRate); - this.updateAllWidget(); + this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate); this.registerListeners(); } } diff --git a/web/monitor.ts b/web/monitor.ts index 09f70a2..22333c6 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,12 +1,13 @@ import { app } from '/scripts/app.js'; import { api } from '/scripts/api.js'; import { commonPrefix } from './common.js'; +import { MonitorUI } from './monitorUI.js'; class CrystoolsMonitor { idExtensionName = 'Crystools.monitor'; menuPrefix = commonPrefix; - htmlIdCrystoolsRoot = 'crystools-root'; - htmlIdCrystoolsMonitorContainer = 'crystools-monitor-container'; + + monitorUI: MonitorUI; idInputRate = 'Crystools.inputRate'; defaultRate = .5; @@ -29,7 +30,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#0AA015', onChange: async(value: boolean) => { - this.updateWidget(this.monitorCPUElement); + this.monitorUI?.updateWidget(this.monitorCPUElement); await this.updateServer({ switchCPU: value, }); @@ -49,7 +50,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#07630D', onChange: async(value: boolean) => { - this.updateWidget(this.monitorRAMElement); + this.monitorUI?.updateWidget(this.monitorRAMElement); await this.updateServer({ switchRAM: value, }); @@ -70,7 +71,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#730F92', onChange: async(value: boolean) => { - this.updateWidget(this.monitorHDDElement); + this.monitorUI?.updateWidget(this.monitorHDDElement); await this.updateServer({ switchHDD: value, }); @@ -119,7 +120,7 @@ class CrystoolsMonitor { } if (valueNumber === 0) { - this.updateAllMonitors({ + this.monitorUI.updateAllMonitors({ cpu_utilization: 0, device: 'cpu', @@ -141,7 +142,7 @@ class CrystoolsMonitor { }); } - this.updateAllAnimationDuration(valueNumber); + this.monitorUI?.updateAllAnimationDuration(valueNumber); }, }); @@ -205,7 +206,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#0C86F4', onChange: async(value: boolean) => { - this.updateWidget(monitorGPUNElement); + this.monitorUI?.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index,{ utilization: value }); @@ -226,7 +227,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: '#176EC7', onChange: async(value: boolean) => { - this.updateWidget(monitorVRAMNElement); + this.monitorUI?.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index,{ vram: value }); @@ -248,7 +249,7 @@ class CrystoolsMonitor { cssColor: '#00ff00', cssColorFinal: '#ff0000', onChange: async(value: boolean) => { - this.updateWidget(monitorTemperatureNElement); + this.monitorUI?.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index,{ temperature: value }); @@ -268,7 +269,6 @@ class CrystoolsMonitor { }); }; - updateServer = async(data: TStatsSettings): Promise => { const resp = await api.fetchApi('/crystools/monitor', { method: 'PATCH', @@ -312,235 +312,28 @@ class CrystoolsMonitor { throw new Error(resp.statusText); }; - updateAllWidget = (): void => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - }; - - updateWidget = (monitorSettings: TMonitorSettings): void => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - }; - - - updateAllMonitors = (data: TStatsData): void => { - // console.log('updateAllMonitors', data); - this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); - - if (data.gpus === undefined || data.gpus.length === 0) { - console.warn('UpdateAllMonitors: no GPU data'); - return; - } - - this.monitorGPUSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.gpu_utilization); - } else { - // console.error('UpdateAllMonitors: no GPU data for index', index); - } - }); - - this.monitorVRAMSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.vram_used_percent); - } else { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - } - }); - - this.monitorTemperatureSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.gpu_temperature); - if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ - monitorSettings.htmlMonitorSliderRef.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; - } - } else { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - } - }); - }; - - updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { - if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { - return; - } - - monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; - monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; - }; - - updateAllAnimationDuration = (value: number): void => { - this.updatedAnimationDuration(this.monitorCPUElement, value); - this.updatedAnimationDuration(this.monitorRAMElement, value); - this.updatedAnimationDuration(this.monitorHDDElement, value); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - }; - - updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { - const slider = monitorSettings.htmlMonitorSliderRef; - if (!slider) { - return; - } - - slider.style.transition = `width ${value.toFixed(1)}s`; - }; - setup(): void { - const parentElement = document.getElementById('queue-button'); - - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); - } - - const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsMonitorContainer); - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'crosshair'; - htmlContainer.style.order = '3'; - htmlContainer.style.margin = '4px 0'; - ctoolsRoot.append(htmlContainer); - - htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - htmlContainer.append(this.createMonitor(this.monitorRAMElement)); - - // gpu0 > gpu1 > vram0 > vram1 - // this.monitorGPUSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - // this.monitorVRAMSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - // this.monitorTemperatureSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - - // gpu0 > vram0 > gpu1 > vram1 - this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); - this.monitorTemperatureSettings[index] && - htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); - }); - - htmlContainer.append(this.createMonitor(this.monitorHDDElement)); - const currentRate = parseFloat(app.ui.settings.getSettingValue(this.idInputRate, this.defaultRate)); - this.updateAllAnimationDuration(currentRate); - this.updateAllWidget(); + + this.monitorUI = new MonitorUI( + this.monitorCPUElement, + this.monitorRAMElement, + this.monitorHDDElement, + this.monitorGPUSettings, + this.monitorVRAMSettings, + this.monitorTemperatureSettings, + currentRate + ); + this.registerListeners(); } - createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { - if (!monitorSettings) { - // just for typescript - return document.createElement('div'); - } - const htmlMain = document.createElement('div'); - htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.style.margin = '2px 10px'; - htmlMain.style.height = '12px'; - htmlMain.style.position = 'relative'; - htmlMain.style.display = 'flex'; - htmlMain.style.alignItems = 'center'; - htmlMain.style.flexDirection = 'row'; - monitorSettings.htmlMonitorRef = htmlMain; - - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.style.width = '35px'; - htmlMonitorText.style.fontSize = '10px'; - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.style.height = '100%'; - htmlMonitorContent.style.flexGrow = '1'; - htmlMonitorContent.style.position = 'relative'; - htmlMonitorContent.style.backgroundColor = 'var(--bg-color)'; - htmlMain.append(htmlMonitorContent); - - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.style.position = 'absolute'; - htmlMonitorSlider.style.height = '100%'; - htmlMonitorSlider.style.width = '0'; - if(monitorSettings.cssColorFinal){ - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.style.position = 'relative'; - htmlMonitorLabel.style.width = '100%'; - htmlMonitorLabel.style.color = 'var(--drag-text)'; - htmlMonitorLabel.style.fontSize = '10px'; - htmlMonitorLabel.innerHTML = '0%'; - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - - return monitorSettings.htmlMonitorRef; - }; - registerListeners = (): void => { api.addEventListener('crystools.monitor', (event: CustomEvent) => { if (event?.detail === undefined) { return; } - this.updateAllMonitors(event.detail); + this.monitorUI.updateAllMonitors(event.detail); }, false); }; } diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts new file mode 100644 index 0000000..696666e --- /dev/null +++ b/web/monitorUI.d.ts @@ -0,0 +1,21 @@ +export declare class MonitorUI { + monitorCPUElement: TMonitorSettings; + monitorRAMElement: TMonitorSettings; + monitorHDDElement: TMonitorSettings; + monitorGPUSettings: TMonitorSettings[]; + monitorVRAMSettings: TMonitorSettings[]; + monitorTemperatureSettings: TMonitorSettings[]; + currentRate: number; + htmlIdCrystoolsRoot: string; + htmlIdCrystoolsMonitorContainer: string; + constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number); + refreshDisplay: () => void; + createVertical: () => void; + updateAllWidget: () => void; + updateWidget: (monitorSettings: TMonitorSettings) => void; + updateAllMonitors: (data: TStatsData) => void; + updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; + updateAllAnimationDuration: (value: number) => void; + updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; + createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; +} diff --git a/web/monitorUI.js b/web/monitorUI.js index 104a702..59ddbf2 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,2 +1,284 @@ -export class monitorUI { +import { app } from '/scripts/app.js'; +export class MonitorUI { + constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { + Object.defineProperty(this, "monitorCPUElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorCPUElement + }); + Object.defineProperty(this, "monitorRAMElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorRAMElement + }); + Object.defineProperty(this, "monitorHDDElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorHDDElement + }); + Object.defineProperty(this, "monitorGPUSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorGPUSettings + }); + Object.defineProperty(this, "monitorVRAMSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorVRAMSettings + }); + Object.defineProperty(this, "monitorTemperatureSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorTemperatureSettings + }); + Object.defineProperty(this, "currentRate", { + enumerable: true, + configurable: true, + writable: true, + value: currentRate + }); + Object.defineProperty(this, "htmlIdCrystoolsRoot", { + enumerable: true, + configurable: true, + writable: true, + value: 'crystools-root' + }); + Object.defineProperty(this, "htmlIdCrystoolsMonitorContainer", { + enumerable: true, + configurable: true, + writable: true, + value: 'crystools-monitor-container' + }); + Object.defineProperty(this, "refreshDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + console.log('refreshDisplay'); + this.updateAllWidget(); + } + }); + Object.defineProperty(this, "createVertical", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + const parentElement = document.getElementById('queue-button'); + let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); + if (!ctoolsRoot) { + ctoolsRoot = document.createElement('div'); + ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); + ctoolsRoot.style.display = 'flex'; + ctoolsRoot.style.width = '100%'; + ctoolsRoot.style.flexDirection = 'column'; + parentElement?.insertAdjacentElement('afterend', ctoolsRoot); + } + const htmlContainer = document.createElement('div'); + htmlContainer.setAttribute('id', this.htmlIdCrystoolsMonitorContainer); + htmlContainer.style.width = '100%'; + htmlContainer.style.cursor = 'crosshair'; + htmlContainer.style.order = '3'; + htmlContainer.style.margin = '4px 0'; + ctoolsRoot.append(htmlContainer); + htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + this.monitorGPUSettings.forEach((_monitorSettings, index) => { + this.monitorGPUSettings[index] && htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); + this.monitorVRAMSettings[index] && htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); + this.monitorTemperatureSettings[index] && + htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); + }); + htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + } + }); + Object.defineProperty(this, "updateAllWidget", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + } + }); + Object.defineProperty(this, "updateWidget", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + } + }); + Object.defineProperty(this, "updateAllMonitors", { + enumerable: true, + configurable: true, + writable: true, + value: (data) => { + this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + if (data.gpus === undefined || data.gpus.length === 0) { + console.warn('UpdateAllMonitors: no GPU data'); + return; + } + this.monitorGPUSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.gpu_utilization); + } + else { + } + }); + this.monitorVRAMSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.vram_used_percent); + } + else { + } + }); + this.monitorTemperatureSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.gpu_temperature); + if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { + monitorSettings.htmlMonitorSliderRef.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; + } + } + else { + } + }); + } + }); + Object.defineProperty(this, "updateMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, percent) => { + if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { + return; + } + monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; + monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; + } + }); + Object.defineProperty(this, "updateAllAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + this.updatedAnimationDuration(this.monitorCPUElement, value); + this.updatedAnimationDuration(this.monitorRAMElement, value); + this.updatedAnimationDuration(this.monitorHDDElement, value); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + } + }); + Object.defineProperty(this, "updatedAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, value) => { + const slider = monitorSettings.htmlMonitorSliderRef; + if (!slider) { + return; + } + slider.style.transition = `width ${value.toFixed(1)}s`; + } + }); + Object.defineProperty(this, "createMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + if (!monitorSettings) { + return document.createElement('div'); + } + const htmlMain = document.createElement('div'); + htmlMain.setAttribute('id', monitorSettings.id); + htmlMain.style.margin = '2px 10px'; + htmlMain.style.height = '12px'; + htmlMain.style.position = 'relative'; + htmlMain.style.display = 'flex'; + htmlMain.style.alignItems = 'center'; + htmlMain.style.flexDirection = 'row'; + monitorSettings.htmlMonitorRef = htmlMain; + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.style.width = '35px'; + htmlMonitorText.style.fontSize = '10px'; + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.style.height = '100%'; + htmlMonitorContent.style.flexGrow = '1'; + htmlMonitorContent.style.position = 'relative'; + htmlMonitorContent.style.backgroundColor = 'var(--bg-color)'; + htmlMain.append(htmlMonitorContent); + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.style.position = 'absolute'; + htmlMonitorSlider.style.height = '100%'; + htmlMonitorSlider.style.width = '0'; + if (monitorSettings.cssColorFinal) { + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } + else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.style.position = 'relative'; + htmlMonitorLabel.style.width = '100%'; + htmlMonitorLabel.style.color = 'var(--drag-text)'; + htmlMonitorLabel.style.fontSize = '10px'; + htmlMonitorLabel.innerHTML = '0%'; + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + return monitorSettings.htmlMonitorRef; + } + }); + this.createVertical(); + window.addEventListener('resize', this.refreshDisplay); + } } diff --git a/web/monitorUI.ts b/web/monitorUI.ts new file mode 100644 index 0000000..ef647f8 --- /dev/null +++ b/web/monitorUI.ts @@ -0,0 +1,247 @@ +import { app } from '/scripts/app.js'; + +export class MonitorUI { + htmlIdCrystoolsRoot = 'crystools-root'; + htmlIdCrystoolsMonitorContainer = 'crystools-monitor-container'; + + constructor( + public monitorCPUElement: TMonitorSettings, + public monitorRAMElement: TMonitorSettings, + public monitorHDDElement: TMonitorSettings, + public monitorGPUSettings: TMonitorSettings[], + public monitorVRAMSettings: TMonitorSettings[], + public monitorTemperatureSettings: TMonitorSettings[], + public currentRate: number + ) { + this.createVertical(); + + window.addEventListener('resize', this.refreshDisplay); + } + + refreshDisplay = (): void => { + console.log('refreshDisplay'); + this.updateAllWidget(); + }; + + createVertical = (): void => { + const parentElement = document.getElementById('queue-button'); + + let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); + if (!ctoolsRoot) { + ctoolsRoot = document.createElement('div'); + ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); + ctoolsRoot.style.display = 'flex'; + ctoolsRoot.style.width = '100%'; + ctoolsRoot.style.flexDirection = 'column'; + parentElement?.insertAdjacentElement('afterend', ctoolsRoot); + } + + const htmlContainer = document.createElement('div'); + htmlContainer.setAttribute('id', this.htmlIdCrystoolsMonitorContainer); + htmlContainer.style.width = '100%'; + htmlContainer.style.cursor = 'crosshair'; + htmlContainer.style.order = '3'; + htmlContainer.style.margin = '4px 0'; + ctoolsRoot.append(htmlContainer); + + htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + + // gpu0 > gpu1 > vram0 > vram1 + // this.monitorGPUSettings.forEach((monitorSettings) => { + // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); + // }); + // this.monitorVRAMSettings.forEach((monitorSettings) => { + // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); + // }); + // this.monitorTemperatureSettings.forEach((monitorSettings) => { + // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); + // }); + + // gpu0 > vram0 > gpu1 > vram1 + this.monitorGPUSettings.forEach((_monitorSettings, index) => { + this.monitorGPUSettings[index] && htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); + this.monitorVRAMSettings[index] && htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); + this.monitorTemperatureSettings[index] && + htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); + }); + + htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + }; + + + updateAllWidget = (): void => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + }; + + updateWidget = (monitorSettings: TMonitorSettings): void => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + }; + + updateAllMonitors = (data: TStatsData): void => { + // console.log('updateAllMonitors', data); + this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + + if (data.gpus === undefined || data.gpus.length === 0) { + console.warn('UpdateAllMonitors: no GPU data'); + return; + } + + this.monitorGPUSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.gpu_utilization); + } else { + // console.error('UpdateAllMonitors: no GPU data for index', index); + } + }); + + this.monitorVRAMSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.vram_used_percent); + } else { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + } + }); + + this.monitorTemperatureSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.gpu_temperature); + if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ + monitorSettings.htmlMonitorSliderRef.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; + } + } else { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + } + }); + }; + + updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { + if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { + return; + } + + monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; + monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; + }; + + updateAllAnimationDuration = (value: number): void => { + this.updatedAnimationDuration(this.monitorCPUElement, value); + this.updatedAnimationDuration(this.monitorRAMElement, value); + this.updatedAnimationDuration(this.monitorHDDElement, value); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + }; + + updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { + const slider = monitorSettings.htmlMonitorSliderRef; + if (!slider) { + return; + } + + slider.style.transition = `width ${value.toFixed(1)}s`; + }; + + + createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { + if (!monitorSettings) { + // just for typescript + return document.createElement('div'); + } + const htmlMain = document.createElement('div'); + htmlMain.setAttribute('id', monitorSettings.id); + htmlMain.style.margin = '2px 10px'; + htmlMain.style.height = '12px'; + htmlMain.style.position = 'relative'; + htmlMain.style.display = 'flex'; + htmlMain.style.alignItems = 'center'; + htmlMain.style.flexDirection = 'row'; + monitorSettings.htmlMonitorRef = htmlMain; + + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.style.width = '35px'; + htmlMonitorText.style.fontSize = '10px'; + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.style.height = '100%'; + htmlMonitorContent.style.flexGrow = '1'; + htmlMonitorContent.style.position = 'relative'; + htmlMonitorContent.style.backgroundColor = 'var(--bg-color)'; + htmlMain.append(htmlMonitorContent); + + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.style.position = 'absolute'; + htmlMonitorSlider.style.height = '100%'; + htmlMonitorSlider.style.width = '0'; + if(monitorSettings.cssColorFinal){ + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.style.position = 'relative'; + htmlMonitorLabel.style.width = '100%'; + htmlMonitorLabel.style.color = 'var(--drag-text)'; + htmlMonitorLabel.style.fontSize = '10px'; + htmlMonitorLabel.innerHTML = '0%'; + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + + return monitorSettings.htmlMonitorRef; + }; +} diff --git a/web/progressBar.ts b/web/progressBar.ts index 044dacb..50a4f8f 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -55,6 +55,7 @@ class CrystoolsProgressBar { this.htmlIdCrystoolsRoot, this.htmlIdCrystoolsProgressBarContainer, this.centerNode); + this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; From f1cd4a5917b65016da3db370c74f6742baa3d816 Mon Sep 17 00:00:00 2001 From: Crystian Date: Fri, 20 Sep 2024 21:20:05 +0200 Subject: [PATCH 04/31] "working" --- tsconfig.json | 23 +- web/common.d.ts | 3 +- web/common.js | 2 +- web/common.ts | 7 +- web/debugger.js | 5 +- web/debugger.ts | 10 +- web/extensions.d.ts | 1 - web/extensions.js | 21 +- web/extensions.ts | 49 +- web/liteGraph.d.ts | 7 +- web/liteGraph.js | 13 - web/liteGraph.ts | 11 +- web/liteGraph.types.d.ts | 12 +- web/types/README.md | 3 + web/types/comfy.d.ts | 227 +++++ web/types/index.d.ts | 55 ++ web/types/litegraph.d.ts | 1750 ++++++++++++++++++++++++++++++++++++++ 17 files changed, 2105 insertions(+), 94 deletions(-) create mode 100644 web/types/README.md create mode 100644 web/types/comfy.d.ts create mode 100644 web/types/index.d.ts create mode 100644 web/types/litegraph.d.ts diff --git a/tsconfig.json b/tsconfig.json index 69b378f..9b4cfe1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,19 +6,20 @@ "typeRoots": [ // "./web/ts/typings", ], - "baseUrl": ".", + "baseUrl": "./", "paths": { - "/scripts/*": ["../../web/scripts/*"], - "/lib/*": ["../../web/lib/*"], - "/extensions/*": ["../../web/extensions/*"], - "/types/*": ["../../web/types/*"] +// "scripts/*": ["../../web/scripts/*"], // works +// "web/*": ["web/*"], // works +// "/lib/*": ["../../web/lib/*"], +// "extensions/*": ["../../web/extensions/*"], + "types/*": ["web/types/*"] }, // "rootDir": "./web/src", - // "rootDir": "../../", - // "rootDirs": [ - // "../../web", +// "rootDir": "../../..", +// "rootDirs": [ +// "../../web", // "web/src" - // ], +// ], "preserveSymlinks": true, "checkJs": false, "allowJs": true, @@ -58,7 +59,9 @@ "noEmit": false }, "include": [ - "./web/*.ts" +// "custom_nodes/ComfyUI-Crystools/web/*.ts", + "web/*.ts", +// "web/types/index.d.ts" ], "exclude": [ "node_modules" diff --git a/web/common.d.ts b/web/common.d.ts index 8685b36..447e59c 100644 --- a/web/common.d.ts +++ b/web/common.d.ts @@ -1,3 +1,4 @@ -import type { ComfyApp, TLGraphNode } from './liteGraph.js'; +import type { TLGraphNode } from './liteGraph.js'; +import { ComfyApp } from 'types/comfy.js'; export declare const commonPrefix = "\uD83E\uDE9B"; export declare function displayContext(nodeType: TLGraphNode, appFromArg: ComfyApp, index?: number, serialize_widgets?: boolean, isVirtualNode?: boolean): void; diff --git a/web/common.js b/web/common.js index 19c221b..51d2dc8 100644 --- a/web/common.js +++ b/web/common.js @@ -1,4 +1,4 @@ -import { ComfyWidgets } from './liteGraph.js'; +import { ComfyWidgets } from '/scripts/widgets.js'; export const commonPrefix = '🪛'; export function displayContext(nodeType, appFromArg, index = 0, serialize_widgets = false, isVirtualNode = false) { function populate(text) { diff --git a/web/common.ts b/web/common.ts index af3c3f3..7ec5771 100644 --- a/web/common.ts +++ b/web/common.ts @@ -1,5 +1,6 @@ -import type { ComfyApp, TLGraphNode } from './liteGraph.js'; -import { ComfyWidgets } from './liteGraph.js'; +import type { TLGraphNode } from './liteGraph.js'; +import { ComfyApp } from 'types/comfy.js'; +import { ComfyWidgets } from '/scripts/widgets.js'; export const commonPrefix = '🪛'; @@ -55,8 +56,8 @@ export function displayContext( // When the node is executed we will be sent the input text, display this in the widget // @ts-ignore const onExecutedOriginal = nodeType.prototype.onExecuted; - // @ts-ignore nodeType.prototype.onExecuted = function(message: { text: string }): void { + // @ts-ignore onExecutedOriginal?.apply(this, arguments); populate.call(this, message.text); }; diff --git a/web/debugger.js b/web/debugger.js index 50596bd..328c1b2 100644 --- a/web/debugger.js +++ b/web/debugger.js @@ -1,7 +1,8 @@ import { app } from '/scripts/app.js'; import { api } from '/scripts/api.js'; import { commonPrefix, displayContext } from './common.js'; -import { LiteGraph, TLGraphNode, ComfyWidgets } from './liteGraph.js'; +import { LiteGraph, TLGraphNode } from './liteGraph.js'; +import { ComfyWidgets } from '/scripts/widgets.js'; app.registerExtension({ name: 'Crystools.Debugger.ConsoleAny', beforeRegisterNodeDef(nodeType, nodeData, appFromArg) { @@ -20,7 +21,7 @@ app.registerExtension({ enumerable: true, configurable: true, writable: true, - value: async () => { + value: () => { return app.graphToPrompt() .then((workflow) => { let result = 'inactive'; diff --git a/web/debugger.ts b/web/debugger.ts index 017bc29..568516b 100644 --- a/web/debugger.ts +++ b/web/debugger.ts @@ -1,8 +1,10 @@ import { app } from '/scripts/app.js'; import { api } from '/scripts/api.js'; import { commonPrefix, displayContext } from './common.js'; -import type { ComfyNode, ComfyApp } from './liteGraph.js'; -import { LiteGraph, TLGraphNode, ComfyWidgets } from './liteGraph.js'; +import type { ComfyNode } from './liteGraph.js'; +import { LiteGraph, TLGraphNode } from './liteGraph.js'; +import { ComfyApp } from 'types/comfy.js'; +import { ComfyWidgets } from '/scripts/widgets.js'; // "Show any" Node app.registerExtension({ @@ -50,9 +52,9 @@ app.registerExtension({ api.addEventListener('executed', this.fillMetadataWidget, false); } - fillMetadataWidget = async (): Promise => { + fillMetadataWidget = (): Promise => { return app.graphToPrompt() - .then((workflow): string => { + .then((workflow: any): string => { let result = 'inactive'; if(this.widgets?.length !== 4) { console.error('Something is wrong with the widgets, should be 4!'); diff --git a/web/extensions.d.ts b/web/extensions.d.ts index cb0ff5c..e69de29 100644 --- a/web/extensions.d.ts +++ b/web/extensions.d.ts @@ -1 +0,0 @@ -export {}; diff --git a/web/extensions.js b/web/extensions.js index 15a9f68..3918c74 100644 --- a/web/extensions.js +++ b/web/extensions.js @@ -1,20 +1 @@ -import { app } from '/scripts/app.js'; -import { displayContext } from './common.js'; -const crystoolsExtensions = { - 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', - 'Preview from image [Crystools]': 'Crystools.Image.PreviewFromImage', - 'Preview from metadata [Crystools]': 'Crystools.Image.PreviewFromMetadata', - 'Metadata comparator [Crystools]': 'Crystools.Metadata.MetadataComparator', - 'Stats system [Crystools]': 'Crystools.Utils.StatsSystem', - 'Show any to JSON [Crystools]': 'Crystools.Debugger.ConsoleAnyToJson', -}; -Object.keys(crystoolsExtensions).forEach(key => { - app.registerExtension({ - name: crystoolsExtensions[key], - beforeRegisterNodeDef(nodeType, nodeData, appFromArg) { - if (nodeData.name === key) { - displayContext(nodeType, appFromArg, 0); - } - }, - }); -}); +"use strict"; diff --git a/web/extensions.ts b/web/extensions.ts index 25a6950..0f4eb95 100644 --- a/web/extensions.ts +++ b/web/extensions.ts @@ -1,24 +1,25 @@ -import { app } from '/scripts/app.js'; -import { displayContext } from './common.js'; -import type { ComfyNode, ComfyApp } from './liteGraph.types'; -import { TLGraphNode } from './liteGraph'; - -const crystoolsExtensions: Record = { - 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', - 'Preview from image [Crystools]': 'Crystools.Image.PreviewFromImage', - 'Preview from metadata [Crystools]': 'Crystools.Image.PreviewFromMetadata', - 'Metadata comparator [Crystools]': 'Crystools.Metadata.MetadataComparator', - 'Stats system [Crystools]': 'Crystools.Utils.StatsSystem', - 'Show any to JSON [Crystools]': 'Crystools.Debugger.ConsoleAnyToJson', -}; - -Object.keys(crystoolsExtensions).forEach(key => { - app.registerExtension({ - name: crystoolsExtensions[key], - beforeRegisterNodeDef(nodeType: ComfyNode, nodeData: TLGraphNode, appFromArg: ComfyApp) { - if (nodeData.name === key) { - displayContext(nodeType, appFromArg, 0); - } - }, - }); -}); +// import { app } from 'scripts/app'; +// import { displayContext } from './common.js'; +// import type { ComfyNode } from './liteGraph.types.js'; +// import { TLGraphNode } from './liteGraph.js'; +// import { ComfyApp } from 'types/comfy.js'; +// +// const crystoolsExtensions: Record = { +// 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', +// 'Preview from image [Crystools]': 'Crystools.Image.PreviewFromImage', +// 'Preview from metadata [Crystools]': 'Crystools.Image.PreviewFromMetadata', +// 'Metadata comparator [Crystools]': 'Crystools.Metadata.MetadataComparator', +// 'Stats system [Crystools]': 'Crystools.Utils.StatsSystem', +// 'Show any to JSON [Crystools]': 'Crystools.Debugger.ConsoleAnyToJson', +// }; +// +// Object.keys(crystoolsExtensions).forEach(key => { +// app.registerExtension({ +// name: crystoolsExtensions[key], +// beforeRegisterNodeDef(nodeType: ComfyNode, nodeData: TLGraphNode, appFromArg: ComfyApp) { +// if (nodeData.name === key) { +// displayContext(nodeType, appFromArg, 0); +// } +// }, +// }); +// }); diff --git a/web/liteGraph.d.ts b/web/liteGraph.d.ts index 054996a..52ecb7e 100644 --- a/web/liteGraph.d.ts +++ b/web/liteGraph.d.ts @@ -1,6 +1,5 @@ -export type * from './liteGraph.types'; -export * from '/scripts/widgets.js'; -import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types'; +export type * from './liteGraph.types.js'; +import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types.js'; declare const LGraphNode: typeof TypeGraphNode; export interface IWidget extends IWidgetOld { onRemove?: () => void; @@ -12,9 +11,7 @@ export declare class TLGraphNode extends LGraphNode { static color: string; static bgcolor: string; static collapsable: boolean; - widgets?: IWidget[]; isVirtualNode?: boolean; - onResize?: (size: [number, number]) => void; widgets_values?: any[]; name?: string; prototype: TLGraphNode; diff --git a/web/liteGraph.js b/web/liteGraph.js index fca4a37..38d7b92 100644 --- a/web/liteGraph.js +++ b/web/liteGraph.js @@ -1,25 +1,12 @@ -export * from '/scripts/widgets.js'; export class TLGraphNode extends LGraphNode { constructor() { super(...arguments); - Object.defineProperty(this, "widgets", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); Object.defineProperty(this, "isVirtualNode", { enumerable: true, configurable: true, writable: true, value: void 0 }); - Object.defineProperty(this, "onResize", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); Object.defineProperty(this, "widgets_values", { enumerable: true, configurable: true, diff --git a/web/liteGraph.ts b/web/liteGraph.ts index 95b8449..73bc3c9 100644 --- a/web/liteGraph.ts +++ b/web/liteGraph.ts @@ -1,9 +1,10 @@ // / // A LOTS OF PATCHES FOR LITEGRAPH TYPES ¯\_(ツ)_/¯ -export type * from './liteGraph.types'; -export * from '/scripts/widgets.js'; +export type * from './liteGraph.types.js'; +// export * from './liteGraph.types'; +// export * from '/scripts/widgets.js'; -import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types'; +import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types.js'; declare const LGraphNode: typeof TypeGraphNode; // just for get the type @@ -20,9 +21,9 @@ export class TLGraphNode extends LGraphNode { static bgcolor: string; static collapsable: boolean; - widgets?: IWidget[]; + // widgets?: IWidget[]; isVirtualNode?: boolean; - onResize?: (size: [number, number]) => void; + // override onResize?: (size: [number, number]) => void; widgets_values?: any[]; name?: string; diff --git a/web/liteGraph.types.d.ts b/web/liteGraph.types.d.ts index bfce629..4ade611 100644 --- a/web/liteGraph.types.d.ts +++ b/web/liteGraph.types.d.ts @@ -1,10 +1,12 @@ // A LOTS OF PATCHES FOR LITEGRAPH TYPES ¯\_(ツ)_/¯ -export type * from '/types/litegraph'; -export type * from '/scripts/widgets'; -export type * from '/scripts/app'; -export type { api } from '/scripts/api'; +import { LGraph } from 'types/litegraph.js'; -import { LGraph, LiteGraph } from '/types/litegraph'; +export type * from 'types/litegraph.js'; +// export type * from 'scripts/widgets'; +// export type * from 'scripts/app'; +// export type { api } from 'scripts/api'; +// +// import { LGraph, LiteGraph } from '/types/litegraph'; export declare type TypeLiteGraph = typeof LiteGraph & { graph: LGraph; diff --git a/web/types/README.md b/web/types/README.md new file mode 100644 index 0000000..3e4c19b --- /dev/null +++ b/web/types/README.md @@ -0,0 +1,3 @@ +The typings in node_modules or in ComfyUI's web/ directory were not that well covered. These typings are hacked together with some of the inconsistencies I found. + +To be honest, I have no idea why I needed a bizarre workaround for litegraph's types. Usually the '/// <reference>' comment should have picked up the types, but it wasn't having it. ¯\_(ツ)_/¯ \ No newline at end of file diff --git a/web/types/comfy.d.ts b/web/types/comfy.d.ts new file mode 100644 index 0000000..bbecb80 --- /dev/null +++ b/web/types/comfy.d.ts @@ -0,0 +1,227 @@ +import type { LGraphGroup as TLGraphGroup, LGraphNode as TLGraphNode, IWidget, SerializedLGraphNode, LGraph as TLGraph, LGraphCanvas as TLGraphCanvas, LiteGraph as TLiteGraph } from "./litegraph.js"; +import type {Constructor, SerializedGraph} from './index.js'; + +declare global { + const LiteGraph: typeof TLiteGraph; + const LGraph: typeof TLGraph; + const LGraphNode: typeof TLGraphNode; + const LGraphCanvas: typeof TLGraphCanvas; + const LGraphGroup: typeof TLGraphGroup; +} + +// @rgthree: Types on ComfyApp as needed. +export interface ComfyApp { + extensions: ComfyExtension[]; + async queuePrompt(number?: number, batchCount = 1): Promise; + graph: TLGraph; + canvas: TLGraphCanvas; + clean() : void; + registerExtension(extension: ComfyExtension): void; + getPreviewFormatParam(): string; + getRandParam(): string; + loadApiJson(apiData: {}, fileName: string): void; + async graphToPrompt(graph?: TLGraph, clean?: boolean): Promise; + // workflow: ComfyWorkflowInstance ??? + async loadGraphData(graphData: {}, clean?: boolean, restore_view?: boolean, workflow?: any|null): Promise + ui: { + settings: { + addSetting(config: {id: string, name: string, type: () => HTMLElement}) : void; + } + } + // Just marking as any for now. + menu?: any; +} + +export interface ComfyWidget extends IWidget { + // https://github.com/comfyanonymous/ComfyUI/issues/2193 Changes from SerializedLGraphNode to + // LGraphNode... + serializeValue(nodeType: TLGraphNode, index: number): Promise; + afterQueued(): void; + inputEl?: HTMLTextAreaElement; + width: number; +} + +export interface ComfyGraphNode extends TLGraphNode { + getExtraMenuOptions: (node: TLGraphNode, options: ContextMenuItem[]) => void; + onExecuted(message: any): void; +} + +export interface ComfyNode extends TLGraphNode { + comfyClass: string; +} + +// @rgthree +export interface ComfyNodeConstructor extends Constructor { + static title: string; + static type?: string; + static comfyClass: string; +} + +export type NodeMode = 0|1|2|3|4|undefined; + + +export interface ComfyExtension { + /** + * The name of the extension + */ + name: string; + /** + * Allows any initialisation, e.g. loading resources. Called after the canvas is created but before nodes are added + * @param app The ComfyUI app instance + */ + init?(app: ComfyApp): Promise; + /** + * Allows any additonal setup, called after the application is fully set up and running + * @param app The ComfyUI app instance + */ + setup?(app: ComfyApp): Promise; + /** + * Called before nodes are registered with the graph + * @param defs The collection of node definitions, add custom ones or edit existing ones + * @param app The ComfyUI app instance + */ + addCustomNodeDefs?(defs: Record, app: ComfyApp): Promise; + /** + * Allows the extension to add custom widgets + * @param app The ComfyUI app instance + * @returns An array of {[widget name]: widget data} + */ + getCustomWidgets?( + app: ComfyApp + ): Promise< + Record { widget?: IWidget; minWidth?: number; minHeight?: number }> + >; + /** + * Allows the extension to add additional handling to the node before it is registered with LGraph + * @rgthree changed nodeType from `typeof LGraphNode` to `ComfyNodeConstructor` + * @param nodeType The node class (not an instance) + * @param nodeData The original node object info config object + * @param app The ComfyUI app instance + */ + beforeRegisterNodeDef?(nodeType: ComfyNodeConstructor, nodeData: ComfyObjectInfo, app: ComfyApp): Promise; + /** + * Allows the extension to register additional nodes with LGraph after standard nodes are added + * @param app The ComfyUI app instance + */ + // @rgthree - add void for non async + registerCustomNodes?(app: ComfyApp): void|Promise; + /** + * Allows the extension to modify a node that has been reloaded onto the graph. + * If you break something in the backend and want to patch workflows in the frontend + * This is the place to do this + * @param node The node that has been loaded + * @param app The ComfyUI app instance + */ + loadedGraphNode?(node: TLGraphNode, app: ComfyApp); + /** + * Allows the extension to run code after the constructor of the node + * @param node The node that has been created + * @param app The ComfyUI app instance + */ + nodeCreated?(node: TLGraphNode, app: ComfyApp); +} + +export type ComfyObjectInfo = { + name: string; + display_name?: string; + description?: string; + category: string; + input?: { + required?: Record; + optional?: Record; + hidden?: Record; + }; + output?: string[]; + output_name: string[]; + // @rgthree + output_node?: boolean; +}; + +export type ComfyObjectInfoConfig = [string | any[]] | [string | any[], any]; + +// @rgthree +type ComfyApiInputLink = [ + /** The id string of the connected node. */ + string, + /** The output index. */ + number, +] + +// @rgthree +export type ComfyApiFormatNode = { + "inputs": { + [input_name: string]: string|number|boolean|ComfyApiInputLink, + }, + "class_type": string, + "_meta": { + "title": string, + } +} + +// @rgthree +export type ComfyApiFormat = { + [node_id: string]: ComfyApiFormatNode +} + +// @rgthree +export type ComfyApiPrompt = { + workflow: SerializedGraph, + output: ComfyApiFormat, +} + +// @rgthree +export type ComfyApiEventDetailStatus = { + exec_info: { + queue_remaining: number; + }; +}; + +// @rgthree +export type ComfyApiEventDetailExecutionStart = { + prompt_id: string; +}; + +// @rgthree +export type ComfyApiEventDetailExecuting = null | string; + +// @rgthree +export type ComfyApiEventDetailProgress = { + node: string; + prompt_id: string; + max: number; + value: number; +}; + +// @rgthree +export type ComfyApiEventDetailExecuted = { + node: string; + prompt_id: string; + output: any; +}; + +// @rgthree +export type ComfyApiEventDetailCached = { + nodes: string[]; + prompt_id: string; +}; + +// @rgthree +export type ComfyApiEventDetailExecuted = { + prompt_id: string; + node: string; + output: any; +}; + +// @rgthree +export type ComfyApiEventDetailError = { + prompt_id: string; + exception_type: string; + exception_message: string; + node_id: string; + node_type: string; + node_id: string; + traceback: string; + executed: any[]; + current_inputs: {[key: string]: (number[]|string[])}; + current_outputs: {[key: string]: (number[]|string[])}; +} diff --git a/web/types/index.d.ts b/web/types/index.d.ts new file mode 100644 index 0000000..a574726 --- /dev/null +++ b/web/types/index.d.ts @@ -0,0 +1,55 @@ +import { LGraph } from "./litegraph.js"; + +export type Constructor = new(...args: any[]) => T; + +export type SerializedLink = [ + number, // this.id, + number, // this.origin_id, + number, // this.origin_slot, + number, // this.target_id, + number, // this.target_slot, + string, // this.type +]; + +export interface SerializedNodeInput { + name: string; + type: string; + link: number; +} +export interface SerializedNodeOutput { + name: string; + type: string; + link: number; + slot_index: number; + links: number[]; +} +export interface SerializedNode { + id: number; + inputs: SerializedNodeInput[]; + outputs: SerializedNodeOutput[]; + mode: number; + order: number; + pos: [number, number]; + properties: any; + size: [number, number]; + type: string; + widgets_values: Array; +} + +export interface SerializedGraph { + config: any; + extra: any; + groups: any; + last_link_id: number; + last_node_id: number; + links: SerializedLink[]; + nodes: SerializedNode[]; +} + +export interface BadLinksData { + hasBadLinks: boolean; + fixed: boolean; + graph: T; + patched: number; + deleted: number; +} diff --git a/web/types/litegraph.d.ts b/web/types/litegraph.d.ts new file mode 100644 index 0000000..730103e --- /dev/null +++ b/web/types/litegraph.d.ts @@ -0,0 +1,1750 @@ +// Type definitions for litegraph.js 0.7.0 +// Project: litegraph.js +// Definitions by: NateScarlet + +export type Vector2 = [number, number]; +export type Vector4 = [number, number, number, number]; +export type widgetTypes = + | "number" + | "slider" + | "combo" + | "text" + | "toggle" + | "button"; +export type SlotShape = + | typeof LiteGraph.BOX_SHAPE + | typeof LiteGraph.CIRCLE_SHAPE + | typeof LiteGraph.ARROW_SHAPE + | typeof LiteGraph.SQUARE_SHAPE + | number; // For custom shapes + +/** https://github.com/jagenjo/litegraph.js/tree/master/guides#node-slots */ +export interface INodeSlot { + name: string; + type: string | -1; + label?: string; + dir?: + | typeof LiteGraph.UP + | typeof LiteGraph.RIGHT + | typeof LiteGraph.DOWN + | typeof LiteGraph.LEFT; + color_on?: string; + color_off?: string; + shape?: SlotShape; + locked?: boolean; + nameLocked?: boolean; + pos?: Vector2; + // @rgthree + hidden?: boolean; + // @rgthree + disabled?: boolean; + // @rgthree - Found this checked in getSlotMenuOptions default. + removable?: boolean; + // @rgthree - A status we put on some nodes so we can draw things around it. + rgthree_status?: 'WARN' | 'ERROR'; +} + +export interface INodeInputSlot extends INodeSlot { + link: LLink["id"] | null; + // @rgthree - add comfy widget info + widget?: { + name: string; + } +} + +export interface INodeOutputSlot extends INodeSlot { + links: LLink["id"][] | null; +} + +export type WidgetCallback = ( + this: T, + value: T["value"], + graphCanvas: LGraphCanvas, + node: LGraphNode, + pos: Vector2, + event?: MouseEvent +) => void; + +// @rgthree +export type WidgetComboCallback = ( + this: T, + value: T["value"][0], + graphCanvas: LGraphCanvas, + node: LGraphNode, + pos: Vector2, + event?: MouseEvent +) => void; + +// @rgthree +export type IWidgetOptions = { + y?: number; // ? + property?: string; + serialize?: boolean; // ComfyUI in app.js + forceInput?: boolean; // ComfyUI in app.js + defaultInput?: boolean; // ComfyUI in app.js +} + +// @rgthree +export type IWidgetToggleOptions = IWidgetOptions & { + on?: string; + off?: string; +} + +// @rgthree +export type IWidgetNumberOptions = IWidgetOptions & { + precision?: number; + max?: number; + min?: number; +} + +// @rgthree +export type IWidgetSliderOptions = IWidgetNumberOptions & { + slider_color?: string; + marker_color?: string; +} + + +// @rgthree +export type IWidgetComboOptions = IWidgetOptions & { + values?: string[] | ((widget: IComboWidget, node: LGraphNode) => string[]); +} + +export interface IWidget { + name: string | null; + // @rgthree + label?: string | null; + value: TValue; + options?: TOptions; + // @rgthree - extend to string for custom + type?: widgetTypes | string; + y?: number; + property?: string; + last_y?: number; + clicked?: boolean; + marker?: boolean; + disabled?: boolean; + callback?: WidgetCallback; + // crystools + onRemove?: () => void; + /** Called by `LGraphCanvas.drawNodeWidgets` */ + draw?( + ctx: CanvasRenderingContext2D, + node: LGraphNode, + width: number, + posY: number, + height: number + ): void; + /** + * Called by `LGraphCanvas.processNodeWidgets` + * https://github.com/jagenjo/litegraph.js/issues/76 + */ + mouse?( + event: MouseEvent, + pos: Vector2, + node: LGraphNode + ): boolean; + /** Called by `LGraphNode.computeSize` */ + computeSize?(width: number): [number, number]; + // @rgthree - make optional, since it is in the code. + serializeValue?(serializedNode: SerializedLGraphNode, widgetIndex: number): TValue; + // @rgthree - Checked in LGraphCanvas.prototype.processNodeWidgets, and figured I'd use it too. + width?: number; +} +export interface IButtonWidget extends IWidget { + type: "button"; +} +// @rgthree: adding options +export interface IToggleWidget extends IWidget { + type: "toggle"; +} +// @rgthree: adding options +export interface ISliderWidget extends IWidget { + type: "slider"; +} +// @rgthree: adding options +export interface INumberWidget extends IWidget { + type: "number"; +} +// @rgthree: adding options +export interface IComboWidget extends IWidget { + value: T[0]; + type: "combo"; + callback?: WidgetComboCallback; +} + +export interface ITextWidget extends IWidget { + type: "text"; +} + +export interface IContextMenuItem { + // @rgthree - Make optional because, I guess it is? + content?: string; + value?: any; + callback?: ContextMenuEventListener; + /** Used as innerHTML for extra child element */ + title?: string; + disabled?: boolean; + has_submenu?: boolean; + submenu?: { + options: ContextMenuItem[]; + } & IContextMenuOptions; + className?: string; + // @rgthree - Added for menu_auto_nest + rgthree_originalValue?: IContextMenuItem; + // @rgthree - this was missing and passed through for getSlotMenuOptions default. + slot?: {input?: INodeInputSlot, output?: INodeOutputSlot}; +} +export interface IContextMenuOptions { + callback?: ContextMenuEventListener; + ignore_item_callbacks?: Boolean; + event?: MouseEvent | CustomEvent | AdjustedMouseEvent; + parentMenu?: ContextMenu|null; + autoopen?: boolean; + title?: string; + extra?: any; + // @rgthree + scale?: number; + // @rgthree + left?: number; + // @rgthree + top?: number; + // @rgthree + className?: string; + // @rgthree - Added for menu_auto_nest + rgthree_originalCallback?: ContextMenuEventListener; + // @rgthree - No idea since it's not documented, but we'll use it to pass data, like rgthree_doNotNest + extra?: any +} + +export type ContextMenuItem = IContextMenuItem | null; +export type ContextMenuEventListener = ( + value: ContextMenuItem, + options: IContextMenuOptions, + event: MouseEvent, + parentMenu: ContextMenu | undefined, + node: LGraphNode +) => boolean | void; + +export const LiteGraph: { + VERSION: number; + + CANVAS_GRID_SIZE: number; + + NODE_TITLE_HEIGHT: number; + NODE_TITLE_TEXT_Y: number; + NODE_SLOT_HEIGHT: number; + NODE_WIDGET_HEIGHT: number; + NODE_WIDTH: number; + NODE_MIN_WIDTH: number; + NODE_COLLAPSED_RADIUS: number; + NODE_COLLAPSED_WIDTH: number; + NODE_TITLE_COLOR: string; + NODE_TEXT_SIZE: number; + NODE_TEXT_COLOR: string; + NODE_SUBTEXT_SIZE: number; + NODE_DEFAULT_COLOR: string; + NODE_DEFAULT_BGCOLOR: string; + NODE_DEFAULT_BOXCOLOR: string; + NODE_DEFAULT_SHAPE: string; + // @rgthree - didn't exist. + NODE_BOX_OUTLINE_COLOR: string; + DEFAULT_SHADOW_COLOR: string; + DEFAULT_GROUP_FONT: number; + // @rgthree - Seems to have been missing. + NODE_BOX_OUTLINE_COLOR: string; + + WIDGET_BGCOLOR: string; + WIDGET_OUTLINE_COLOR: string; + WIDGET_TEXT_COLOR: string; + WIDGET_SECONDARY_TEXT_COLOR: string; + + LINK_COLOR: string; + EVENT_LINK_COLOR: string; + CONNECTING_LINK_COLOR: string; + + MAX_NUMBER_OF_NODES: number; //avoid infinite loops + DEFAULT_POSITION: Vector2; //default node position + VALID_SHAPES: ["default", "box", "round", "card"]; //,"circle" + + //shapes are used for nodes but also for slots + BOX_SHAPE: 1; + ROUND_SHAPE: 2; + CIRCLE_SHAPE: 3; + CARD_SHAPE: 4; + ARROW_SHAPE: 5; + GRID_SHAPE: 6; + + //enums + INPUT: 1; + OUTPUT: 2; + + EVENT: -1; //for outputs + ACTION: -1; //for inputs + + ALWAYS: 0; + ON_EVENT: 1; + NEVER: 2; + ON_TRIGGER: 3; + + UP: 1; + DOWN: 2; + LEFT: 3; + RIGHT: 4; + CENTER: 5; + + STRAIGHT_LINK: 0; + LINEAR_LINK: 1; + SPLINE_LINK: 2; + + NORMAL_TITLE: 0; + NO_TITLE: 1; + TRANSPARENT_TITLE: 2; + AUTOHIDE_TITLE: 3; + + node_images_path: string; + + // @rgthree. These just weren't there. Note, LiteGraph initializes these as an array, but + // ComfyUI overrides these to a string-keye'd object... ??? + slot_types_default_out: {[key: string]: string[]}; + slot_types_default_in: {[key: string]: string[]}; + + debug: boolean; + catch_exceptions: boolean; + throw_errors: boolean; + /** if set to true some nodes like Formula would be allowed to evaluate code that comes from unsafe sources (like node configuration), which could lead to exploits */ + allow_scripts: boolean; + /** node types by string */ + registered_node_types: Record; + /** used for dropping files in the canvas */ + node_types_by_file_extension: Record; + /** node types by class name */ + Nodes: Record; + + /** used to add extra features to the search box */ + searchbox_extras: Record< + string, + { + data: { outputs: string[][]; title: string }; + desc: string; + type: string; + } + >; + + //@rgthree + isValidConnection(type: string|string[], type: string|string[]):boolean; + overlapBounding(a: Vector4, b: Vector4) : boolean; + + createNode(type: string): T; + /** Register a node class so it can be listed when the user wants to create a new one */ + registerNodeType(type: string, base: { new (title?: string): T }): void; + /** removes a node type from the system */ + unregisterNodeType(type: string): void; + /** Removes all previously registered node's types. */ + clearRegisteredTypes(): void; + /** + * Create a new node type by passing a function, it wraps it with a proper class and generates inputs according to the parameters of the function. + * Useful to wrap simple methods that do not require properties, and that only process some input to generate an output. + * @param name node name with namespace (p.e.: 'math/sum') + * @param func + * @param param_types an array containing the type of every parameter, otherwise parameters will accept any type + * @param return_type string with the return type, otherwise it will be generic + * @param properties properties to be configurable + */ + wrapFunctionAsNode( + name: string, + func: (...args: any[]) => any, + param_types?: string[], + return_type?: string, + properties?: object + ): void; + + /** + * Adds this method to all node types, existing and to be created + * (You can add it to LGraphNode.prototype but then existing node types wont have it) + */ + addNodeMethod(name: string, func: (...args: any[]) => any): void; + + /** + * Create a node of a given type with a name. The node is not attached to any graph yet. + * @param type full name of the node class. p.e. "math/sin" + * @param name a name to distinguish from other nodes + * @param options to set options + */ + createNode( + type: string, + title: string, + options: object + ): T; + + /** + * Returns a registered node type with a given name + * @param type full name of the node class. p.e. "math/sin" + */ + getNodeType(type: string): LGraphNodeConstructor; + + /** + * Returns a list of node types matching one category + * @method getNodeTypesInCategory + * @param {String} category category name + * @param {String} filter only nodes with ctor.filter equal can be shown + * @return {Array} array with all the node classes + */ + getNodeTypesInCategory( + category: string, + filter: string + ): LGraphNodeConstructor[]; + + /** + * Returns a list with all the node type categories + * @method getNodeTypesCategories + * @param {String} filter only nodes with ctor.filter equal can be shown + * @return {Array} array with all the names of the categories + */ + getNodeTypesCategories(filter: string): string[]; + + /** debug purposes: reloads all the js scripts that matches a wildcard */ + reloadNodes(folder_wildcard: string): void; + + getTime(): number; + LLink: typeof LLink; + LGraph: typeof LGraph; + DragAndScale: typeof DragAndScale; + compareObjects(a: object, b: object): boolean; + distance(a: Vector2, b: Vector2): number; + colorToString(c: string): string; + isInsideRectangle( + x: number, + y: number, + left: number, + top: number, + width: number, + height: number + ): boolean; + growBounding(bounding: Vector4, x: number, y: number): Vector4; + isInsideBounding(p: Vector2, bb: Vector4): boolean; + hex2num(hex: string): [number, number, number]; + num2hex(triplet: [number, number, number]): string; + ContextMenu: typeof ContextMenu; + extendClass(target: A, origin: B): A & B; + getParameterNames(func: string): string[]; + // @rgthree + closeAllContextMenus(ref_window?: Window): void; +}; + +export type serializedLGraph< + TNode = ReturnType, + // https://github.com/jagenjo/litegraph.js/issues/74 + TLink = [number, number, number, number, number, string], + TGroup = ReturnType +> = { + last_node_id: LGraph["last_node_id"]; + last_link_id: LGraph["last_link_id"]; + nodes: TNode[]; + links: TLink[]; + groups: TGroup[]; + config: LGraph["config"]; + version: typeof LiteGraph.VERSION; +}; + +export declare class LGraph { + static supported_types: string[]; + static STATUS_STOPPED: 1; + static STATUS_RUNNING: 2; + + constructor(o?: object); + + filter: string; + catch_errors: boolean; + /** custom data */ + config: object; + elapsed_time: number; + fixedtime: number; + fixedtime_lapse: number; + globaltime: number; + inputs: any; + iteration: number; + last_link_id: number; + last_node_id: number; + last_update_time: number; + links: Record; + list_of_graphcanvas: LGraphCanvas[]; + outputs: any; + runningtime: number; + starttime: number; + status: typeof LGraph.STATUS_RUNNING | typeof LGraph.STATUS_STOPPED; + + // @rgthree, remove private; it's not really private b/c it's javascript. + _nodes: LGraphNode[]; + // @rgthree, remove private; it's not really private b/c it's javascript. + _groups: LGraphGroup[]; + private _nodes_by_id: Record; + /** nodes that are executable sorted in execution order */ + private _nodes_executable: + | (LGraphNode & { onExecute: NonNullable }[]) + | null; + /** nodes that contain onExecute */ + private _nodes_in_order: LGraphNode[]; + private _version: number; + + getSupportedTypes(): string[]; + /** Removes all nodes from this graph */ + clear(): void; + /** Attach Canvas to this graph */ + attachCanvas(graphCanvas: LGraphCanvas): void; + /** Detach Canvas to this graph */ + detachCanvas(graphCanvas: LGraphCanvas): void; + /** + * Starts running this graph every interval milliseconds. + * @param interval amount of milliseconds between executions, if 0 then it renders to the monitor refresh rate + */ + start(interval?: number): void; + /** Stops the execution loop of the graph */ + stop(): void; + /** + * Run N steps (cycles) of the graph + * @param num number of steps to run, default is 1 + */ + runStep(num?: number, do_not_catch_errors?: boolean): void; + /** + * Updates the graph execution order according to relevance of the nodes (nodes with only outputs have more relevance than + * nodes with only inputs. + */ + updateExecutionOrder(): void; + /** This is more internal, it computes the executable nodes in order and returns it */ + computeExecutionOrder(only_onExecute: boolean, set_level: any): T; + /** + * Returns all the nodes that could affect this one (ancestors) by crawling all the inputs recursively. + * It doesn't include the node itself + * @return an array with all the LGraphNodes that affect this node, in order of execution + */ + getAncestors(node: LGraphNode): LGraphNode[]; + /** + * Positions every node in a more readable manner + */ + arrange(margin?: number,layout?: string): void; + /** + * Returns the amount of time the graph has been running in milliseconds + * @return number of milliseconds the graph has been running + */ + getTime(): number; + + /** + * Returns the amount of time accumulated using the fixedtime_lapse var. This is used in context where the time increments should be constant + * @return number of milliseconds the graph has been running + */ + getFixedTime(): number; + + /** + * Returns the amount of time it took to compute the latest iteration. Take into account that this number could be not correct + * if the nodes are using graphical actions + * @return number of milliseconds it took the last cycle + */ + getElapsedTime(): number; + /** + * Sends an event to all the nodes, useful to trigger stuff + * @param eventName the name of the event (function to be called) + * @param params parameters in array format + */ + sendEventToAllNodes(eventName: string, params: any[], mode?: any): void; + + sendActionToCanvas(action: any, params: any[]): void; + /** + * Adds a new node instance to this graph + * @param node the instance of the node + */ + add(node: LGraphNode, skip_compute_order?: boolean): void; + /** + * Called when a new node is added + * @param node the instance of the node + */ + onNodeAdded(node: LGraphNode): void; + /** Removes a node from the graph */ + remove(node: LGraphNode): void; + /** + * Returns a node by its id. + * @rgthree - make id options/nullable. + */ + getNodeById(id?: number|null): LGraphNode | undefined; + /** + * Returns a list of nodes that matches a class + * @param classObject the class itself (not an string) + * @return a list with all the nodes of this type + */ + findNodesByClass( + classObject: LGraphNodeConstructor + ): T[]; + /** + * Returns a list of nodes that matches a type + * @param type the name of the node type + * @return a list with all the nodes of this type + */ + findNodesByType(type: string): T[]; + /** + * Returns the first node that matches a name in its title + * @param title the name of the node to search + * @return the node or null + */ + findNodeByTitle(title: string): T | null; + /** + * Returns a list of nodes that matches a name + * @param title the name of the node to search + * @return a list with all the nodes with this name + */ + findNodesByTitle(title: string): T[]; + /** + * Returns the top-most node in this position of the canvas + * @param x the x coordinate in canvas space + * @param y the y coordinate in canvas space + * @param nodes_list a list with all the nodes to search from, by default is all the nodes in the graph + * @return the node at this position or null + */ + getNodeOnPos( + x: number, + y: number, + node_list?: LGraphNode[], + margin?: number + ): T | null; + /** + * Returns the top-most group in that position + * @param x the x coordinate in canvas space + * @param y the y coordinate in canvas space + * @return the group or null + */ + getGroupOnPos(x: number, y: number): LGraphGroup | null; + + onAction(action: any, param: any): void; + trigger(action: any, param: any): void; + /** Tell this graph it has a global graph input of this type */ + addInput(name: string, type: string, value?: any): void; + /** Assign a data to the global graph input */ + setInputData(name: string, data: any): void; + /** Returns the current value of a global graph input */ + getInputData(name: string): T; + /** Changes the name of a global graph input */ + renameInput(old_name: string, name: string): false | undefined; + /** Changes the type of a global graph input */ + changeInputType(name: string, type: string): false | undefined; + /** Removes a global graph input */ + removeInput(name: string): boolean; + /** Creates a global graph output */ + addOutput(name: string, type: string, value: any): void; + /** Assign a data to the global output */ + setOutputData(name: string, value: string): void; + /** Returns the current value of a global graph output */ + getOutputData(name: string): T; + + /** Renames a global graph output */ + renameOutput(old_name: string, name: string): false | undefined; + /** Changes the type of a global graph output */ + changeOutputType(name: string, type: string): false | undefined; + /** Removes a global graph output */ + removeOutput(name: string): boolean; + triggerInput(name: string, value: any): void; + setCallback(name: string, func: (...args: any[]) => any): void; + beforeChange(info?: LGraphNode): void; + afterChange(info?: LGraphNode): void; + connectionChange(node: LGraphNode): void; + /** returns if the graph is in live mode */ + isLive(): boolean; + /** clears the triggered slot animation in all links (stop visual animation) */ + clearTriggeredSlots(): void; + /* Called when something visually changed (not the graph!) */ + change(): void; + setDirtyCanvas(fg: boolean, bg: boolean): void; + /** Destroys a link */ + removeLink(link_id: number): void; + /** Creates a Object containing all the info about this graph, it can be serialized */ + serialize(): T; + /** + * Configure a graph from a JSON string + * @param data configure a graph from a JSON string + * @returns if there was any error parsing + */ + configure(data: object, keep_old?: boolean): boolean | undefined; + load(url: string): void; +} + +export type SerializedLLink = [number, string, number, number, number, number]; +export declare class LLink { + id: number; + type: string; + origin_id: number; + origin_slot: number; + target_id: number; + target_slot: number; + constructor( + id: number, + type: string, + origin_id: number, + origin_slot: number, + target_id: number, + target_slot: number + ); + configure(o: LLink | SerializedLLink): void; + serialize(): SerializedLLink; + // @rgthree + color?: string; +} + +export type SerializedLGraphNode = { + id: T["id"]; + type: T["type"]; + pos: T["pos"]; + size: T["size"]; + flags: T["flags"]; + mode: T["mode"]; + inputs: T["inputs"]; + outputs: T["outputs"]; + title: T["title"]; + properties: T["properties"]; + widgets_values?: IWidget["value"][]; +}; + +/** https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#lgraphnode */ +export declare class LGraphNode { + + // @rgthree added + findInputSlotByType(type: string, returnObj?: boolean, preferFreeSlot?: boolean, doNotUseOccupied?: boolean): number + findOutputSlotByType(type: string, returnObj?: boolean, preferFreeSlot?: boolean, doNotUseOccupied?: boolean): number + onShowCustomPanelInfo(panel: HTMLElement): void; + onDblClick?(event: AdjustedMouseEvent, pos: Vector2, canvas: LGraphCanvas): void; + inResizeCorner(x: number, y:number) : boolean; + onWidgetChanged?(widgetName: string, widgetValue: any, oldWidgetValue: any, widget: IWidget): void; + + // end @rgthree added + + static title_color?: string; + static title: string; + static type: null | string; + static widgets_up: boolean; + constructor(title?: string); + + title: string; + // @rgthree - made undefined since ComfyNode does it (even through LiteGraph does not..) + type?: null | string; + size: Vector2; + graph: null | LGraph; + graph_version: number; + pos: Vector2; + is_selected: boolean; + mouseOver: boolean; + // @rgthree - missing. + block_delete: boolean; + + id: number; + + widgets: IWidget[]; + //inputs available: array of inputs + inputs: INodeInputSlot[]; + outputs: INodeOutputSlot[]; + connections: any[]; + + // @rgthree + _collapsed_width?: number; + + //local data + properties: Record; + properties_info: any[]; + + flags: Partial<{ + collapsed: boolean + // @rgthree + allow_interaction: boolean; + // @rgthree + pinned: boolean; + }>; + + color: string; + bgcolor: string; + boxcolor: string; + shape: + | typeof LiteGraph.BOX_SHAPE + | typeof LiteGraph.ROUND_SHAPE + | typeof LiteGraph.CIRCLE_SHAPE + | typeof LiteGraph.CARD_SHAPE + | typeof LiteGraph.ARROW_SHAPE; + + serialize_widgets: boolean; + skip_list: boolean; + + /** Used in `LGraphCanvas.onMenuNodeMode` */ + mode?: + | typeof LiteGraph.ON_EVENT + | typeof LiteGraph.ON_TRIGGER + | typeof LiteGraph.NEVER + | typeof LiteGraph.ALWAYS + | 4; // Comfy App "Bypass" + + /** If set to true widgets do not start after the slots */ + widgets_up: boolean; + /** widgets start at y distance from the top of the node */ + widgets_start_y: number; + /** if you render outside the node, it will be clipped */ + clip_area: boolean; + /** if set to false it wont be resizable with the mouse */ + resizable: boolean; + /** slots are distributed horizontally */ + horizontal: boolean; + /** if true, the node will show the bgcolor as 'red' */ + has_errors?: boolean; + + // @rgthree + setSize(size: Vector2): void; + onResize?(size: Vector2): void; + onInputClick(slot: number, event: MouseEvent): void; + onOutputClick(slot: number, event: MouseEvent): void; + getConnectionPos(isInput: boolean, slotNumber: number, out: Vector2): Vector2; + + /** configure a node from an object containing the serialized info */ + configure(info: SerializedLGraphNode): void; + /** serialize the content */ + serialize(): SerializedLGraphNode; + /** Creates a clone of this node */ + clone(): this; + /** serialize and stringify */ + toString(): string; + /** get the title string */ + getTitle(): string; + /** sets the value of a property */ + setProperty(name: string, value: any): void; + /** sets the output data */ + setOutputData(slot: number, data: any): void; + /** sets the output data */ + setOutputDataType(slot: number, type: string): void; + /** + * Retrieves the input data (data traveling through the connection) from one slot + * @param slot + * @param force_update if set to true it will force the connected node of this slot to output data into this link + * @return data or if it is not connected returns undefined + */ + getInputData(slot: number, force_update?: boolean): T; + /** + * Retrieves the input data type (in case this supports multiple input types) + * @param slot + * @return datatype in string format + */ + getInputDataType(slot: number): string; + /** + * Retrieves the input data from one slot using its name instead of slot number + * @param slot_name + * @param force_update if set to true it will force the connected node of this slot to output data into this link + * @return data or if it is not connected returns null + */ + getInputDataByName(slot_name: string, force_update?: boolean): T; + /** tells you if there is a connection in one input slot */ + isInputConnected(slot: number): boolean; + /** tells you info about an input connection (which node, type, etc) */ + getInputInfo( + slot: number + ): { link: number; name: string; type: string | 0 } | null; + /** returns the node connected in the input slot */ + getInputNode(slot: number): LGraphNode | null; + /** returns the value of an input with this name, otherwise checks if there is a property with that name */ + getInputOrProperty(name: string): T; + /** tells you the last output data that went in that slot */ + getOutputData(slot: number): T | null; + /** tells you info about an output connection (which node, type, etc) */ + getOutputInfo( + slot: number + ): { name: string; type: string; links: number[] } | null; + /** tells you if there is a connection in one output slot */ + isOutputConnected(slot: number): boolean; + /** tells you if there is any connection in the output slots */ + isAnyOutputConnected(): boolean; + /** retrieves all the nodes connected to this output slot */ + getOutputNodes(slot: number): LGraphNode[]; + /** Triggers an event in this node, this will trigger any output with the same name */ + trigger(action: string, param: any): void; + /** + * Triggers an slot event in this node + * @param slot the index of the output slot + * @param param + * @param link_id in case you want to trigger and specific output link in a slot + */ + triggerSlot(slot: number, param: any, link_id?: number): void; + /** + * clears the trigger slot animation + * @param slot the index of the output slot + * @param link_id in case you want to trigger and specific output link in a slot + */ + clearTriggeredSlot(slot: number, link_id?: number): void; + /** + * add a new property to this node + * @param name + * @param default_value + * @param type string defining the output type ("vec3","number",...) + * @param extra_info this can be used to have special properties of the property (like values, etc) + */ + addProperty( + name: string, + default_value: any, + type: string, + extra_info?: object + ): T; + /** + * add a new output slot to use in this node + * @param name + * @param type string defining the output type ("vec3","number",...) + * @param extra_info this can be used to have special properties of an output (label, special color, position, etc) + */ + addOutput( + name: string, + type: string | -1, + extra_info?: Partial + ): INodeOutputSlot; + /** + * add a new output slot to use in this node + * @param array of triplets like [[name,type,extra_info],[...]] + */ + addOutputs( + array: [string, string | -1, Partial | undefined][] + ): void; + /** remove an existing output slot */ + removeOutput(slot: number): void; + /** + * add a new input slot to use in this node + * @param name + * @param type string defining the input type ("vec3","number",...), it its a generic one use 0 + * @param extra_info this can be used to have special properties of an input (label, color, position, etc) + */ + addInput( + name: string, + type: string | -1, + extra_info?: Partial + ): INodeInputSlot; + /** + * add several new input slots in this node + * @param array of triplets like [[name,type,extra_info],[...]] + */ + addInputs( + array: [string, string | -1, Partial | undefined][] + ): void; + /** remove an existing input slot */ + removeInput(slot: number): void; + /** + * add an special connection to this node (used for special kinds of graphs) + * @param name + * @param type string defining the input type ("vec3","number",...) + * @param pos position of the connection inside the node + * @param direction if is input or output + */ + addConnection( + name: string, + type: string, + pos: Vector2, + direction: string + ): { + name: string; + type: string; + pos: Vector2; + direction: string; + links: null; + }; + setValue(v: any): void; + /** computes the size of a node according to its inputs and output slots */ + computeSize(out?: Vector2): [number, number]; + /** + * https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#node-widgets + * @return created widget + */ + addWidget( + type: T["type"], + name: string, + value: T["value"], + // @rgthree + callback?: T["callback"] | string,//WidgetCallback | string, + options?: T["options"] + ): T; + + addCustomWidget(customWidget: T): T; + + /** + * returns the bounding of the object, used for rendering purposes + * @return [x, y, width, height] + */ + getBounding(): Vector4; + /** checks if a point is inside the shape of a node */ + isPointInside( + x: number, + y: number, + margin?: number, + skipTitle?: boolean + ): boolean; + /** checks if a point is inside a node slot, and returns info about which slot */ + getSlotInPosition( + x: number, + y: number + ): { + input?: INodeInputSlot; + output?: INodeOutputSlot; + slot: number; + link_pos: Vector2; + }; + /** + * returns the input slot with a given name (used for dynamic slots), -1 if not found + * @param name the name of the slot + * @return the slot (-1 if not found) + */ + findInputSlot(name: string): number; + /** + * returns the output slot with a given name (used for dynamic slots), -1 if not found + * @param name the name of the slot + * @return the slot (-1 if not found) + */ + findOutputSlot(name: string): number; + /** + * connect this node output to the input of another node + * @param slot (could be the number of the slot or the string with the name of the slot) + * @param targetNode the target node + * @param targetSlot the input slot of the target node (could be the number of the slot or the string with the name of the slot, or -1 to connect a trigger) + * @return {Object} the link_info is created, otherwise null + */ + connect( + slot: number | string, + targetNode: LGraphNode, + targetSlot: number | string + ): T | null; + + connectByTypeOutput( + slot: number | string, + sourceNode: LGraphNode, + sourceSlotType: string, + optsIn: string + ): T | null; + + connectByType( + slot: number | string, + sourceNode: LGraphNode, + sourceSlotType: string, + optsIn: string + ): T | null; + + + /** + * disconnect one output to an specific node + * @param slot (could be the number of the slot or the string with the name of the slot) + * @param target_node the target node to which this slot is connected [Optional, if not target_node is specified all nodes will be disconnected] + * @return if it was disconnected successfully + */ + disconnectOutput(slot: number | string, targetNode?: LGraphNode): boolean; + /** + * disconnect one input + * @param slot (could be the number of the slot or the string with the name of the slot) + * @return if it was disconnected successfully + */ + disconnectInput(slot: number | string): boolean; + /** + * returns the center of a connection point in canvas coords + * @param is_input true if if a input slot, false if it is an output + * @param slot (could be the number of the slot or the string with the name of the slot) + * @param out a place to store the output, to free garbage + * @return the position + **/ + getConnectionPos( + is_input: boolean, + slot: number | string, + out?: Vector2 + ): Vector2; + /** Force align to grid */ + alignToGrid(): void; + /** Console output */ + trace(msg: string): void; + /** Forces to redraw or the main canvas (LGraphNode) or the bg canvas (links) */ + setDirtyCanvas(fg: boolean, bg: boolean): void; + loadImage(url: string): void; + /** Allows to get onMouseMove and onMouseUp events even if the mouse is out of focus */ + captureInput(v: any): void; + /** Collapse the node to make it smaller on the canvas */ + collapse(force: boolean): void; + /** Forces the node to do not move or realign on Z */ + pin(v?: boolean): void; + localToScreen(x: number, y: number, graphCanvas: LGraphCanvas): Vector2; + + // https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#custom-node-appearance + onDrawBackground?( + ctx: CanvasRenderingContext2D, + // @rgthree fixed + canvas: LGraphCanvas + ): void; + onDrawForeground?( + ctx: CanvasRenderingContext2D, + // @rgthree fixed + canvas: LGraphCanvas + ): void; + + // https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#custom-node-behaviour + onMouseDown?( + event: MouseEvent, + pos: Vector2, + graphCanvas: LGraphCanvas + ): void; + onMouseMove?( + event: MouseEvent, + pos: Vector2, + graphCanvas: LGraphCanvas + ): void; + onMouseUp?( + event: MouseEvent, + pos: Vector2, + graphCanvas: LGraphCanvas + ): void; + onMouseEnter?( + event: MouseEvent, + pos: Vector2, + graphCanvas: LGraphCanvas + ): void; + onMouseLeave?( + event: MouseEvent, + pos: Vector2, + graphCanvas: LGraphCanvas + ): void; + onKey?(event: KeyboardEvent, pos: Vector2, graphCanvas: LGraphCanvas): void; + // @rgthree + onKeyDown?(event: KeyboardEvent): void; + // @rgthree + onKeyUp?(event: KeyboardEvent): void; + + onExecuted(message: any): void; + /** Called by `LGraphNode.createNode` */ + onNodeCreated?(): void; + /** Called by `LGraphCanvas.selectNodes` */ + onSelected?(): void; + /** Called by `LGraphCanvas.deselectNode` */ + onDeselected?(): void; + /** Called by `LGraph.runStep` `LGraphNode.getInputData` */ + onExecute?(): void; + /** Called by `LGraph.serialize` */ + onSerialize?(o: SerializedLGraphNode): void; + /** Called by `LGraph.configure` */ + onConfigure?(o: SerializedLGraphNode): void; + /** + * when added to graph (warning: this is called BEFORE the node is configured when loading) + * Called by `LGraph.add` + */ + onAdded?(graph: LGraph): void; + /** + * when removed from graph + * Called by `LGraph.remove` `LGraph.clear` + */ + onRemoved?(): void; + /** + * if returns false the incoming connection will be canceled + * Called by `LGraph.connect` + * @param inputIndex target input slot number + * @param outputType type of output slot + * @param outputSlot output slot object + * @param outputNode node containing the output + * @param outputIndex index of output slot + */ + onConnectInput?( + inputIndex: number, + outputType: INodeOutputSlot["type"], + outputSlot: INodeOutputSlot, + outputNode: LGraphNode, + outputIndex: number + ): boolean; + /** + * if returns false the incoming connection will be canceled + * Called by `LGraph.connect` + * @param outputIndex target output slot number + * @param inputType type of input slot + * @param inputSlot input slot object + * @param inputNode node containing the input + * @param inputIndex index of input slot + */ + onConnectOutput?( + outputIndex: number, + inputType: INodeInputSlot["type"], + inputSlot: INodeInputSlot, + inputNode: LGraphNode, + inputIndex: number + ): boolean; + + /** + * Called just before connection (or disconnect - if input is linked). + * A convenient place to switch to another input, or create new one. + * This allow for ability to automatically add slots if needed + * @param inputIndex + * @return selected input slot index, can differ from parameter value + */ + onBeforeConnectInput?( + inputIndex: number + ): number; + + /** a connection changed (new one or removed) (LiteGraph.INPUT or LiteGraph.OUTPUT, slot, true if connected, link_info, input_info or output_info ) */ + onConnectionsChange( + type: number, + slotIndex: number, + isConnected: boolean, + link: LLink, + // @rgthree - Make it INodeSlot instead of union + ioSlot: INodeSlot + ): void; + + /** + * if returns false, will abort the `LGraphNode.setProperty` + * Called when a property is changed + * @param property + * @param value + * @param prevValue + */ + onPropertyChanged?(property: string, value: any, prevValue: any): void | boolean; + + /** Called by `LGraphCanvas.processContextMenu` */ + getMenuOptions?(graphCanvas: LGraphCanvas): ContextMenuItem[]; + // @rgthree. This is fixed because the INodeSlot is wrong and, also, null can be returned to not trigger a menu. + // getSlotMenuOptions?(slot: INodeSlot): ContextMenuItem[]; + getSlotMenuOptions(slot: {input?: INodeInputSlot, output?: INodeOutputSlot}): ContextMenuItem[] | null; + + getExtraMenuOptions?(canvas: LGraphCanvas, options: ContextMenuItem[]): void; + + // @rgthree - Called in LiteGraph.core when the properties panel is constructed. + onShowCustomPanelInfo(panel: HTMLElement): void; +} + +export type LGraphNodeConstructor = { + new (): T; + + // @rgthree + title_mode?: + typeof LiteGraph.NORMAL_TITLE | + typeof LiteGraph.TRANSPARENT_TITLE | + typeof LiteGraph.AUTOHIDE_TITLE | + typeof LiteGraph.NO_TITLE; + title: string; + category: string; + type: string; + comfyClass?: string; +}; + +export type SerializedLGraphGroup = { + title: LGraphGroup["title"]; + bounding: LGraphGroup["_bounding"]; + color: LGraphGroup["color"]; + font: LGraphGroup["font"]; +}; +export declare class LGraphGroup { + title: string; + // @rgthree - mark unprivate + _bounding: Vector4; + // @rgthree - updated to make optional because it seems to be so. + color?: string|null; + font: string; + // @rgthree + _nodes: LGraphNode[]; + // @rgthree + _pos: Vector2; + // @rgthree + _size: Vector2; + // @rgthree + graph: LGraph; + // @rgthree - apparently it is available? + size: Vector2; + // @rgthree - apparently it is available? + pos: Vector2; + + + configure(o: SerializedLGraphGroup): void; + serialize(): SerializedLGraphGroup; + move(deltaX: number, deltaY: number, ignoreNodes?: boolean): void; + recomputeInsideNodes(): void; + isPointInside: LGraphNode["isPointInside"]; + setDirtyCanvas: LGraphNode["setDirtyCanvas"]; +} + +export declare class DragAndScale { + constructor(element?: HTMLElement, skipEvents?: boolean); + offset: [number, number]; + scale: number; + max_scale: number; + min_scale: number; + onredraw: Function | null; + enabled: boolean; + last_mouse: Vector2; + element: HTMLElement | null; + visible_area: Vector4; + bindEvents(element: HTMLElement): void; + computeVisibleArea(): void; + onMouse(e: MouseEvent): void; + toCanvasContext(ctx: CanvasRenderingContext2D): void; + convertOffsetToCanvas(pos: Vector2): Vector2; + convertCanvasToOffset(pos: Vector2): Vector2; + mouseDrag(x: number, y: number): void; + changeScale(value: number, zooming_center?: Vector2): void; + changeDeltaScale(value: number, zooming_center?: Vector2): void; + reset(): void; +} + +// @rgthree. +interface CanvasDivDialog extends HTMLDivElement { + close: () => void; + modified: () => void; + is_modified: boolean; +} + +/** + * This class is in charge of rendering one graph inside a canvas. And provides all the interaction required. + * Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked + * + * @param canvas the canvas where you want to render (it accepts a selector in string format or the canvas element itself) + * @param graph + * @param options { skip_rendering, autoresize } + */ +export declare class LGraphCanvas { + static node_colors: Record< + string, + { + color: string; + bgcolor: string; + groupcolor: string; + } + >; + static link_type_colors: Record; + static gradients: object; + static search_limit: number; + + static getFileExtension(url: string): string; + static decodeHTML(str: string): string; + + static onMenuCollapseAll(): void; + static onMenuNodeEdit(): void; + static onShowPropertyEditor( + item: any, + options: any, + e: any, + menu: any, + node: any + ): void; + /** Create menu for `Add Group` */ + static onGroupAdd: ContextMenuEventListener; + /** Create menu for `Add Node` */ + static onMenuAdd: ContextMenuEventListener; + static showMenuNodeOptionalInputs: ContextMenuEventListener; + static showMenuNodeOptionalOutputs: ContextMenuEventListener; + static onShowMenuNodeProperties: ContextMenuEventListener; + static onResizeNode: ContextMenuEventListener; + static onMenuNodeCollapse: ContextMenuEventListener; + static onMenuNodePin: ContextMenuEventListener; + static onMenuNodeMode: ContextMenuEventListener; + static onMenuNodeColors: ContextMenuEventListener; + static onMenuNodeShapes: ContextMenuEventListener; + static onMenuNodeRemove: ContextMenuEventListener; + static onMenuNodeClone: ContextMenuEventListener; + + // @rgthree + static onShowPropertyEditor: ContextMenuEventListener; + + constructor( + canvas: HTMLCanvasElement | string, + graph?: LGraph, + options?: { + skip_render?: boolean; + autoresize?: boolean; + } + ); + + // @rgthree. This was "HTMLCanvasElement" but that is just wrong... it's LGraphCanvas + static active_canvas: LGraphCanvas; + + // @rgthree + pointer_is_down: boolean; + + allow_dragcanvas: boolean; + allow_dragnodes: boolean; + /** allow to control widgets, buttons, collapse, etc */ + allow_interaction: boolean; + /** allows to change a connection with having to redo it again */ + allow_reconnect_links: boolean; + /** allow selecting multi nodes without pressing extra keys */ + multi_select: boolean; + /** No effect */ + allow_searchbox: boolean; + always_render_background: boolean; + autoresize?: boolean; + background_image: string; + bgcanvas: HTMLCanvasElement; + bgctx: CanvasRenderingContext2D; + canvas: HTMLCanvasElement; + canvas_mouse: Vector2; + // @rgthree - Looks like this is to replace canvas_mouse. + graph_mouse: Vector2; + clear_background: boolean; + // connecting_node: LGraphNode | null; + // // @rgthree - for overriding. + // _connecting_node: LGraphNode | null; + // @rgthree + // connecting_input: INodeInputSlot | null; + // // @rgthree + // connecting_output: INodeOutputSlot | null; + // // @rgthree + // connecting_slot: number; + // // @rgthree + // connecting_pos: Vector2 | null; + // @rgthree - for some reason, the new comfyUI update renamed connecting_node to connecting_links (maybe) + connecting_links: { + node: LGraphNode, input?: INodeInputSlot, output?: INodeOutputSlot, pos: Vector2, slot: number + }[] | null; + _connecting_links: this['connecting_links'] | null; + + connections_width: number; + ctx: CanvasRenderingContext2D; + current_node: LGraphNode | null; + default_connection_color: { + input_off: string; + input_on: string; + output_off: string; + output_on: string; + }; + default_link_color: string; + dirty_area: Vector4 | null; + dirty_bgcanvas?: boolean; + dirty_canvas?: boolean; + drag_mode: boolean; + dragging_canvas: boolean; + dragging_rectangle: Vector4 | null; + // @rgthree; mark undefined. + // It doesn't look like this should ever be undefined.. but something changed in Comfy and folks + // reported https://github.com/rgthree/rgthree-comfy/issues/71. I couldn't reproduce, but we can + // handle it. + ds?: DragAndScale; + /** used for transition */ + editor_alpha: number; + filter: any; + fps: number; + frame: number; + graph: LGraph; + highlighted_links: Record; + highquality_render: boolean; + inner_text_font: string; + is_rendering: boolean; + last_draw_time: number; + last_mouse: Vector2; + /** + * Possible duplicated with `last_mouse` + * https://github.com/jagenjo/litegraph.js/issues/70 + */ + last_mouse_position: Vector2; + /** Timestamp of last mouse click, defaults to 0 */ + last_mouseclick: number; + links_render_mode: + | typeof LiteGraph.STRAIGHT_LINK + | typeof LiteGraph.LINEAR_LINK + | typeof LiteGraph.SPLINE_LINK; + live_mode: boolean; + node_capturing_input: LGraphNode | null; + node_dragged: LGraphNode | null; + node_in_panel: LGraphNode | null; + node_over: LGraphNode | null; + node_title_color: string; + node_widget: [LGraphNode, IWidget] | null; + /** Called by `LGraphCanvas.drawBackCanvas` */ + onDrawBackground: + | ((ctx: CanvasRenderingContext2D, visibleArea: Vector4) => void) + | null; + /** Called by `LGraphCanvas.drawFrontCanvas` */ + onDrawForeground: + | ((ctx: CanvasRenderingContext2D, visibleArea: Vector4) => void) + | null; + onDrawOverlay: ((ctx: CanvasRenderingContext2D) => void) | null; + /** Called by `LGraphCanvas.processMouseDown` */ + onMouse: ((event: MouseEvent) => boolean) | null; + /** Called by `LGraphCanvas.drawFrontCanvas` and `LGraphCanvas.drawLinkTooltip` */ + onDrawLinkTooltip: ((ctx: CanvasRenderingContext2D, link: LLink, _this: this) => void) | null; + /** Called by `LGraphCanvas.selectNodes` */ + onNodeMoved: ((node: LGraphNode) => void) | null; + /** Called by `LGraphCanvas.processNodeSelected` */ + onNodeSelected: ((node: LGraphNode) => void) | null; + /** Called by `LGraphCanvas.deselectNode` */ + onNodeDeselected: ((node: LGraphNode) => void) | null; + /** Called by `LGraphCanvas.processNodeDblClicked` */ + onShowNodePanel: ((node: LGraphNode) => void) | null; + /** Called by `LGraphCanvas.processNodeDblClicked` */ + onNodeDblClicked: ((node: LGraphNode) => void) | null; + /** Called by `LGraphCanvas.selectNodes` */ + onSelectionChange: ((nodes: Record) => void) | null; + /** Called by `LGraphCanvas.showSearchBox` */ + onSearchBox: + | (( + helper: Element, + value: string, + graphCanvas: LGraphCanvas + ) => string[]) + | null; + onSearchBoxSelection: + | ((name: string, event: MouseEvent, graphCanvas: LGraphCanvas) => void) + | null; + pause_rendering: boolean; + render_canvas_border: boolean; + render_collapsed_slots: boolean; + render_connection_arrows: boolean; + render_connections_border: boolean; + render_connections_shadows: boolean; + render_curved_connections: boolean; + render_execution_order: boolean; + render_only_selected: boolean; + render_shadows: boolean; + render_title_colored: boolean; + round_radius: number; + selected_group: null | LGraphGroup; + selected_group_resizing: boolean; + selected_nodes: Record; + show_info: boolean; + title_text_font: string; + /** set to true to render title bar with gradients */ + use_gradients: boolean; + visible_area: DragAndScale["visible_area"]; + visible_links: LLink[]; + visible_nodes: LGraphNode[]; + zoom_modify_alpha: boolean; + + /** clears all the data inside */ + clear(): void; + /** assigns a graph, you can reassign graphs to the same canvas */ + setGraph(graph: LGraph, skipClear?: boolean): void; + /** opens a graph contained inside a node in the current graph */ + openSubgraph(graph: LGraph): void; + /** closes a subgraph contained inside a node */ + closeSubgraph(): void; + /** assigns a canvas */ + setCanvas(canvas: HTMLCanvasElement, skipEvents?: boolean): void; + /** binds mouse, keyboard, touch and drag events to the canvas */ + bindEvents(): void; + /** unbinds mouse events from the canvas */ + unbindEvents(): void; + + /** + * this function allows to render the canvas using WebGL instead of Canvas2D + * this is useful if you plant to render 3D objects inside your nodes, it uses litegl.js for webgl and canvas2DtoWebGL to emulate the Canvas2D calls in webGL + **/ + enableWebGL(): void; + + /** + * marks as dirty the canvas, this way it will be rendered again + * @param fg if the foreground canvas is dirty (the one containing the nodes) + * @param bg if the background canvas is dirty (the one containing the wires) + */ + setDirty(fg: boolean, bg: boolean): void; + + /** + * Used to attach the canvas in a popup + * @return the window where the canvas is attached (the DOM root node) + */ + getCanvasWindow(): Window; + /** starts rendering the content of the canvas when needed */ + startRendering(): void; + /** stops rendering the content of the canvas (to save resources) */ + stopRendering(): void; + + processMouseDown(e: MouseEvent): boolean | undefined; + processMouseMove(e: MouseEvent): boolean | undefined; + processMouseUp(e: MouseEvent): boolean | undefined; + processMouseWheel(e: MouseEvent): boolean | undefined; + + /** returns true if a position (in graph space) is on top of a node little corner box */ + isOverNodeBox(node: LGraphNode, canvasX: number, canvasY: number): boolean; + /** returns true if a position (in graph space) is on top of a node input slot */ + isOverNodeInput( + node: LGraphNode, + canvasX: number, + canvasY: number, + slotPos: Vector2 + ): boolean; + + /** process a key event */ + processKey(e: KeyboardEvent): boolean | undefined; + + // @rgthree - added param + copyToClipboard(nodes: LGraphNode[]|{[key:number]:LGraphNode}): void; + pasteFromClipboard(): void; + processDrop(e: DragEvent): void; + checkDropItem(e: DragEvent): void; + processNodeDblClicked(n: LGraphNode): void; + processNodeSelected(n: LGraphNode, e: MouseEvent): void; + processNodeDeselected(node: LGraphNode): void; + + /** selects a given node (or adds it to the current selection) */ + selectNode(node: LGraphNode, add?: boolean): void; + /** selects several nodes (or adds them to the current selection) */ + selectNodes(nodes?: LGraphNode[], add?: boolean): void; + /** removes a node from the current selection */ + deselectNode(node: LGraphNode): void; + /** removes all nodes from the current selection */ + deselectAllNodes(): void; + /** deletes all nodes in the current selection from the graph */ + deleteSelectedNodes(): void; + + /** centers the camera on a given node */ + // @rgthree - narrow parameter + centerOnNode(node: {pos: Vector2, size: Vector2}): void; + /** changes the zoom level of the graph (default is 1), you can pass also a place used to pivot the zoom */ + setZoom(value: number, center: Vector2): void; + /** brings a node to front (above all other nodes) */ + bringToFront(node: LGraphNode): void; + /** sends a node to the back (below all other nodes) */ + sendToBack(node: LGraphNode): void; + /** checks which nodes are visible (inside the camera area) */ + computeVisibleNodes(nodes: LGraphNode[]): LGraphNode[]; + /** renders the whole canvas content, by rendering in two separated canvas, one containing the background grid and the connections, and one containing the nodes) */ + draw(forceFG?: boolean, forceBG?: boolean): void; + /** draws the front canvas (the one containing all the nodes) */ + drawFrontCanvas(): void; + /** draws some useful stats in the corner of the canvas */ + renderInfo(ctx: CanvasRenderingContext2D, x: number, y: number): void; + /** draws the back canvas (the one containing the background and the connections) */ + drawBackCanvas(): void; + /** draws the given node inside the canvas */ + drawNode(node: LGraphNode, ctx: CanvasRenderingContext2D): void; + /** draws graphic for node's slot */ + drawSlotGraphic(ctx: CanvasRenderingContext2D, pos: number[], shape: SlotShape, horizontal: boolean): void; + /** draws the shape of the given node in the canvas */ + drawNodeShape( + node: LGraphNode, + ctx: CanvasRenderingContext2D, + size: [number, number], + fgColor: string, + bgColor: string, + selected: boolean, + mouseOver: boolean + ): void; + /** draws every connection visible in the canvas */ + drawConnections(ctx: CanvasRenderingContext2D): void; + /** + * draws a link between two points + * @param a start pos + * @param b end pos + * @param link the link object with all the link info + * @param skipBorder ignore the shadow of the link + * @param flow show flow animation (for events) + * @param color the color for the link + * @param startDir the direction enum + * @param endDir the direction enum + * @param numSublines number of sublines (useful to represent vec3 or rgb) + **/ + renderLink( + a: Vector2, + b: Vector2, + link: object, + skipBorder: boolean, + flow: boolean, + color?: string, + startDir?: number, + endDir?: number, + numSublines?: number + ): void; + + computeConnectionPoint( + a: Vector2, + b: Vector2, + t: number, + startDir?: number, + endDir?: number + ): void; + + drawExecutionOrder(ctx: CanvasRenderingContext2D): void; + /** draws the widgets stored inside a node */ + drawNodeWidgets( + node: LGraphNode, + posY: number, + ctx: CanvasRenderingContext2D, + activeWidget: object + ): void; + /** process an event on widgets */ + processNodeWidgets( + node: LGraphNode, + pos: Vector2, + event: Event, + activeWidget: object + ): void; + /** draws every group area in the background */ + drawGroups(canvas: any, ctx: CanvasRenderingContext2D): void; + adjustNodesSize(): void; + /** resizes the canvas to a given size, if no size is passed, then it tries to fill the parentNode */ + resize(width?: number, height?: number): void; + /** + * switches to live mode (node shapes are not rendered, only the content) + * this feature was designed when graphs where meant to create user interfaces + **/ + switchLiveMode(transition?: boolean): void; + onNodeSelectionChange(): void; + touchHandler(event: TouchEvent): void; + + showLinkMenu(link: LLink, e: any): false; + prompt( + title: string, + value: any, + callback: Function, + event: any + ): HTMLDivElement; + showSearchBox(event?: MouseEvent): void; + showEditPropertyValue(node: LGraphNode, property: any, options: any): void; + createDialog( + html: string, + options?: { position?: Vector2; event?: MouseEvent } + // @rgthree - Fix return type from void (added above) + ): CanvasDivDialog; + + + + convertOffsetToCanvas: DragAndScale["convertOffsetToCanvas"]; + convertCanvasToOffset: DragAndScale["convertCanvasToOffset"]; + /** converts event coordinates from canvas2D to graph coordinates */ + // @rgthree - change MouseEvent to less restrictive {clientX: number, clientY: number} that + // implementation uses. + convertEventToCanvasOffset(e: {clientX: number, clientY: number}): Vector2; + /** adds some useful properties to a mouse event, like the position in graph coordinates */ + adjustMouseEvent(e: MouseEvent): void; + + getCanvasMenuOptions(): ContextMenuItem[]; + getNodeMenuOptions(node: LGraphNode): ContextMenuItem[]; + getGroupMenuOptions(): ContextMenuItem[]; + /** Called by `getCanvasMenuOptions`, replace default options */ + getMenuOptions?(): ContextMenuItem[]; + /** Called by `getCanvasMenuOptions`, append to default options */ + getExtraMenuOptions?(): ContextMenuItem[]; + /** Called when mouse right click */ + processContextMenu(node: LGraphNode, event: Event): void; + + // @rgthree - Adding this for ComfyUI, since they add this in their own overload in app.js + selected_group_moving?: boolean; + + // @rgthree + showShowNodePanel(node: LGraphNode): void; +} + +// @rgthree - The adjusted pointer event after calling adjustMouseEvent +export interface AdjustedMouseEvent extends PointerEvent { + deltaX: number; + deltaY: number; + canvasX: number; + canvasY: number; +} + +declare class ContextMenu { + static trigger( + element: HTMLElement, + event_name: string, + params: any, + origin: any + ): void; + static isCursorOverElement(event: MouseEvent, element: HTMLElement): void; + static closeAllContextMenus(window: Window): void; + constructor(values: ContextMenuItem[]|string[], options?: IContextMenuOptions, window?: Window); + options: IContextMenuOptions; + parentMenu?: ContextMenu; + lock: boolean; + current_submenu?: ContextMenu; + addItem( + name: string, + value: ContextMenuItem, + options?: IContextMenuOptions + ): void; + close(e?: MouseEvent, ignore_parent_menu?: boolean): void; + getTopMenu(): void; + getFirstEvent(): void; +} + +declare global { + interface Math { + clamp(v: number, min: number, max: number): number; + } +} From 82063a746c0313fdfcf00fa7f15993ed38ba0a2d Mon Sep 17 00:00:00 2001 From: Crystian Date: Fri, 20 Sep 2024 23:30:00 +0200 Subject: [PATCH 05/31] working! --- tsconfig.json | 17 +++++++++++------ web/common.d.ts | 2 +- web/common.ts | 6 +++++- web/debugger.ts | 2 +- web/liteGraph.types.d.ts | 4 ++-- web/{types => typings}/README.md | 0 web/{types => typings}/comfy.d.ts | 0 web/{types => typings}/index.d.ts | 0 web/{types => typings}/litegraph.d.ts | 0 9 files changed, 20 insertions(+), 11 deletions(-) rename web/{types => typings}/README.md (100%) rename web/{types => typings}/comfy.d.ts (100%) rename web/{types => typings}/index.d.ts (100%) rename web/{types => typings}/litegraph.d.ts (100%) diff --git a/tsconfig.json b/tsconfig.json index 9b4cfe1..87aebbd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,20 +6,24 @@ "typeRoots": [ // "./web/ts/typings", ], +// "rootDir": "../../web", "baseUrl": "./", "paths": { + "/scripts/*": ["../../web/scripts/*"], // works +// "scripts/*": ["scripts/*"], // works // "scripts/*": ["../../web/scripts/*"], // works // "web/*": ["web/*"], // works // "/lib/*": ["../../web/lib/*"], // "extensions/*": ["../../web/extensions/*"], - "types/*": ["web/types/*"] +// "types/*": ["web/types/*"] }, // "rootDir": "./web/src", -// "rootDir": "../../..", -// "rootDirs": [ + "rootDirs": [ +// "../../web/scripts", // "../../web", - // "web/src" -// ], + "web" +// "../../web" + ], "preserveSymlinks": true, "checkJs": false, "allowJs": true, @@ -59,7 +63,8 @@ "noEmit": false }, "include": [ -// "custom_nodes/ComfyUI-Crystools/web/*.ts", +// "./custom_nodes/ComfyUI-Crystools/web/*.ts", +// "../../web/*.ts", "web/*.ts", // "web/types/index.d.ts" ], diff --git a/web/common.d.ts b/web/common.d.ts index 447e59c..68067c0 100644 --- a/web/common.d.ts +++ b/web/common.d.ts @@ -1,4 +1,4 @@ import type { TLGraphNode } from './liteGraph.js'; -import { ComfyApp } from 'types/comfy.js'; +import { ComfyApp } from './typings/comfy.js'; export declare const commonPrefix = "\uD83E\uDE9B"; export declare function displayContext(nodeType: TLGraphNode, appFromArg: ComfyApp, index?: number, serialize_widgets?: boolean, isVirtualNode?: boolean): void; diff --git a/web/common.ts b/web/common.ts index 7ec5771..389b2e8 100644 --- a/web/common.ts +++ b/web/common.ts @@ -1,5 +1,7 @@ import type { TLGraphNode } from './liteGraph.js'; -import { ComfyApp } from 'types/comfy.js'; +import { ComfyApp } from './typings/comfy.js'; +// import { ComfyWidgets } from '../../scripts/widgets.js'; +// import { ComfyWidgets } from './widgets.js'; import { ComfyWidgets } from '/scripts/widgets.js'; export const commonPrefix = '🪛'; @@ -54,7 +56,9 @@ export function displayContext( } // When the node is executed we will be sent the input text, display this in the widget + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/unbound-method const onExecutedOriginal = nodeType.prototype.onExecuted; nodeType.prototype.onExecuted = function(message: { text: string }): void { // @ts-ignore diff --git a/web/debugger.ts b/web/debugger.ts index 568516b..18c7f43 100644 --- a/web/debugger.ts +++ b/web/debugger.ts @@ -3,7 +3,7 @@ import { api } from '/scripts/api.js'; import { commonPrefix, displayContext } from './common.js'; import type { ComfyNode } from './liteGraph.js'; import { LiteGraph, TLGraphNode } from './liteGraph.js'; -import { ComfyApp } from 'types/comfy.js'; +import { ComfyApp } from './typings/comfy.js'; import { ComfyWidgets } from '/scripts/widgets.js'; // "Show any" Node diff --git a/web/liteGraph.types.d.ts b/web/liteGraph.types.d.ts index 4ade611..2ac3ab3 100644 --- a/web/liteGraph.types.d.ts +++ b/web/liteGraph.types.d.ts @@ -1,7 +1,7 @@ // A LOTS OF PATCHES FOR LITEGRAPH TYPES ¯\_(ツ)_/¯ -import { LGraph } from 'types/litegraph.js'; +import { LGraph } from './typings/litegraph.js'; -export type * from 'types/litegraph.js'; +export type * from './typings/litegraph.js'; // export type * from 'scripts/widgets'; // export type * from 'scripts/app'; // export type { api } from 'scripts/api'; diff --git a/web/types/README.md b/web/typings/README.md similarity index 100% rename from web/types/README.md rename to web/typings/README.md diff --git a/web/types/comfy.d.ts b/web/typings/comfy.d.ts similarity index 100% rename from web/types/comfy.d.ts rename to web/typings/comfy.d.ts diff --git a/web/types/index.d.ts b/web/typings/index.d.ts similarity index 100% rename from web/types/index.d.ts rename to web/typings/index.d.ts diff --git a/web/types/litegraph.d.ts b/web/typings/litegraph.d.ts similarity index 100% rename from web/types/litegraph.d.ts rename to web/typings/litegraph.d.ts From 0b17bdc321f592add6fc4e6c7ca8785d5282189f Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 01:28:13 +0200 Subject: [PATCH 06/31] folder comfy --- tsconfig.json | 2 +- web/{ => comfy}/liteGraph.d.ts | 1 + web/{ => comfy}/liteGraph.js | 1 + web/{ => comfy}/liteGraph.ts | 2 +- web/{ => comfy}/liteGraph.types.d.ts | 0 web/{ => comfy}/typings/README.md | 8 ++-- web/{ => comfy}/typings/comfy.d.ts | 0 web/{ => comfy}/typings/index.d.ts | 0 web/{ => comfy}/typings/litegraph.d.ts | 0 web/common.d.ts | 4 +- web/common.ts | 6 +-- web/debugger.js | 2 +- web/debugger.ts | 6 +-- web/extensions.d.ts | 1 + web/extensions.js | 21 ++++++++- web/extensions.ts | 50 ++++++++++----------- web/monitor.types.d.ts | 57 ------------------------ web/progressBar.js | 3 +- web/progressBar.ts | 3 +- web/progressBarUI.d.ts | 6 ++- web/progressBarUI.js | 7 ++- web/progressBarUI.ts | 7 ++- web/types.d.ts | 61 ++++++++++++++++++++++++-- web/types.js | 6 --- web/types.ts | 5 --- 25 files changed, 139 insertions(+), 120 deletions(-) rename web/{ => comfy}/liteGraph.d.ts (94%) rename web/{ => comfy}/liteGraph.js (95%) rename web/{ => comfy}/liteGraph.ts (96%) rename web/{ => comfy}/liteGraph.types.d.ts (100%) rename web/{ => comfy}/typings/README.md (92%) rename web/{ => comfy}/typings/comfy.d.ts (100%) rename web/{ => comfy}/typings/index.d.ts (100%) rename web/{ => comfy}/typings/litegraph.d.ts (100%) delete mode 100644 web/monitor.types.d.ts delete mode 100644 web/types.js delete mode 100644 web/types.ts diff --git a/tsconfig.json b/tsconfig.json index 87aebbd..ca96d32 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -66,7 +66,7 @@ // "./custom_nodes/ComfyUI-Crystools/web/*.ts", // "../../web/*.ts", "web/*.ts", -// "web/types/index.d.ts" +// "web/types.d.ts" ], "exclude": [ "node_modules" diff --git a/web/liteGraph.d.ts b/web/comfy/liteGraph.d.ts similarity index 94% rename from web/liteGraph.d.ts rename to web/comfy/liteGraph.d.ts index 52ecb7e..460b065 100644 --- a/web/liteGraph.d.ts +++ b/web/comfy/liteGraph.d.ts @@ -1,4 +1,5 @@ export type * from './liteGraph.types.js'; +export * from '/scripts/widgets.js'; import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types.js'; declare const LGraphNode: typeof TypeGraphNode; export interface IWidget extends IWidgetOld { diff --git a/web/liteGraph.js b/web/comfy/liteGraph.js similarity index 95% rename from web/liteGraph.js rename to web/comfy/liteGraph.js index 38d7b92..bc661ca 100644 --- a/web/liteGraph.js +++ b/web/comfy/liteGraph.js @@ -1,3 +1,4 @@ +export * from '/scripts/widgets.js'; export class TLGraphNode extends LGraphNode { constructor() { super(...arguments); diff --git a/web/liteGraph.ts b/web/comfy/liteGraph.ts similarity index 96% rename from web/liteGraph.ts rename to web/comfy/liteGraph.ts index 73bc3c9..f9785f6 100644 --- a/web/liteGraph.ts +++ b/web/comfy/liteGraph.ts @@ -2,7 +2,7 @@ // A LOTS OF PATCHES FOR LITEGRAPH TYPES ¯\_(ツ)_/¯ export type * from './liteGraph.types.js'; // export * from './liteGraph.types'; -// export * from '/scripts/widgets.js'; +export * from '/scripts/widgets.js'; import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types.js'; diff --git a/web/liteGraph.types.d.ts b/web/comfy/liteGraph.types.d.ts similarity index 100% rename from web/liteGraph.types.d.ts rename to web/comfy/liteGraph.types.d.ts diff --git a/web/typings/README.md b/web/comfy/typings/README.md similarity index 92% rename from web/typings/README.md rename to web/comfy/typings/README.md index 3e4c19b..58fde3e 100644 --- a/web/typings/README.md +++ b/web/comfy/typings/README.md @@ -1,3 +1,5 @@ -The typings in node_modules or in ComfyUI's web/ directory were not that well covered. These typings are hacked together with some of the inconsistencies I found. - -To be honest, I have no idea why I needed a bizarre workaround for litegraph's types. Usually the '/// <reference>' comment should have picked up the types, but it wasn't having it. ¯\_(ツ)_/¯ \ No newline at end of file +COPIED FROM rgthree + +The typings in node_modules or in ComfyUI's web/ directory were not that well covered. These typings are hacked together with some of the inconsistencies I found. + +To be honest, I have no idea why I needed a bizarre workaround for litegraph's types. Usually the '/// <reference>' comment should have picked up the types, but it wasn't having it. ¯\_(ツ)_/¯ diff --git a/web/typings/comfy.d.ts b/web/comfy/typings/comfy.d.ts similarity index 100% rename from web/typings/comfy.d.ts rename to web/comfy/typings/comfy.d.ts diff --git a/web/typings/index.d.ts b/web/comfy/typings/index.d.ts similarity index 100% rename from web/typings/index.d.ts rename to web/comfy/typings/index.d.ts diff --git a/web/typings/litegraph.d.ts b/web/comfy/typings/litegraph.d.ts similarity index 100% rename from web/typings/litegraph.d.ts rename to web/comfy/typings/litegraph.d.ts diff --git a/web/common.d.ts b/web/common.d.ts index 68067c0..a7605e0 100644 --- a/web/common.d.ts +++ b/web/common.d.ts @@ -1,4 +1,4 @@ -import type { TLGraphNode } from './liteGraph.js'; -import { ComfyApp } from './typings/comfy.js'; +import type { TLGraphNode } from './comfy/liteGraph.js'; +import { ComfyApp } from './comfy/typings/comfy.js'; export declare const commonPrefix = "\uD83E\uDE9B"; export declare function displayContext(nodeType: TLGraphNode, appFromArg: ComfyApp, index?: number, serialize_widgets?: boolean, isVirtualNode?: boolean): void; diff --git a/web/common.ts b/web/common.ts index 389b2e8..c002713 100644 --- a/web/common.ts +++ b/web/common.ts @@ -1,7 +1,5 @@ -import type { TLGraphNode } from './liteGraph.js'; -import { ComfyApp } from './typings/comfy.js'; -// import { ComfyWidgets } from '../../scripts/widgets.js'; -// import { ComfyWidgets } from './widgets.js'; +import type { TLGraphNode } from './comfy/liteGraph.js'; +import { ComfyApp } from './comfy/typings/comfy.js'; import { ComfyWidgets } from '/scripts/widgets.js'; export const commonPrefix = '🪛'; diff --git a/web/debugger.js b/web/debugger.js index 328c1b2..70d954b 100644 --- a/web/debugger.js +++ b/web/debugger.js @@ -1,7 +1,7 @@ import { app } from '/scripts/app.js'; import { api } from '/scripts/api.js'; import { commonPrefix, displayContext } from './common.js'; -import { LiteGraph, TLGraphNode } from './liteGraph.js'; +import { LiteGraph, TLGraphNode } from './comfy/liteGraph.js'; import { ComfyWidgets } from '/scripts/widgets.js'; app.registerExtension({ name: 'Crystools.Debugger.ConsoleAny', diff --git a/web/debugger.ts b/web/debugger.ts index 18c7f43..c518748 100644 --- a/web/debugger.ts +++ b/web/debugger.ts @@ -1,9 +1,9 @@ import { app } from '/scripts/app.js'; import { api } from '/scripts/api.js'; import { commonPrefix, displayContext } from './common.js'; -import type { ComfyNode } from './liteGraph.js'; -import { LiteGraph, TLGraphNode } from './liteGraph.js'; -import { ComfyApp } from './typings/comfy.js'; +import type { ComfyNode } from './comfy/liteGraph.js'; +import { LiteGraph, TLGraphNode } from './comfy/liteGraph.js'; +import { ComfyApp } from './comfy/typings/comfy.js'; import { ComfyWidgets } from '/scripts/widgets.js'; // "Show any" Node diff --git a/web/extensions.d.ts b/web/extensions.d.ts index e69de29..cb0ff5c 100644 --- a/web/extensions.d.ts +++ b/web/extensions.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/web/extensions.js b/web/extensions.js index 3918c74..15a9f68 100644 --- a/web/extensions.js +++ b/web/extensions.js @@ -1 +1,20 @@ -"use strict"; +import { app } from '/scripts/app.js'; +import { displayContext } from './common.js'; +const crystoolsExtensions = { + 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', + 'Preview from image [Crystools]': 'Crystools.Image.PreviewFromImage', + 'Preview from metadata [Crystools]': 'Crystools.Image.PreviewFromMetadata', + 'Metadata comparator [Crystools]': 'Crystools.Metadata.MetadataComparator', + 'Stats system [Crystools]': 'Crystools.Utils.StatsSystem', + 'Show any to JSON [Crystools]': 'Crystools.Debugger.ConsoleAnyToJson', +}; +Object.keys(crystoolsExtensions).forEach(key => { + app.registerExtension({ + name: crystoolsExtensions[key], + beforeRegisterNodeDef(nodeType, nodeData, appFromArg) { + if (nodeData.name === key) { + displayContext(nodeType, appFromArg, 0); + } + }, + }); +}); diff --git a/web/extensions.ts b/web/extensions.ts index 0f4eb95..1071ce6 100644 --- a/web/extensions.ts +++ b/web/extensions.ts @@ -1,25 +1,25 @@ -// import { app } from 'scripts/app'; -// import { displayContext } from './common.js'; -// import type { ComfyNode } from './liteGraph.types.js'; -// import { TLGraphNode } from './liteGraph.js'; -// import { ComfyApp } from 'types/comfy.js'; -// -// const crystoolsExtensions: Record = { -// 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', -// 'Preview from image [Crystools]': 'Crystools.Image.PreviewFromImage', -// 'Preview from metadata [Crystools]': 'Crystools.Image.PreviewFromMetadata', -// 'Metadata comparator [Crystools]': 'Crystools.Metadata.MetadataComparator', -// 'Stats system [Crystools]': 'Crystools.Utils.StatsSystem', -// 'Show any to JSON [Crystools]': 'Crystools.Debugger.ConsoleAnyToJson', -// }; -// -// Object.keys(crystoolsExtensions).forEach(key => { -// app.registerExtension({ -// name: crystoolsExtensions[key], -// beforeRegisterNodeDef(nodeType: ComfyNode, nodeData: TLGraphNode, appFromArg: ComfyApp) { -// if (nodeData.name === key) { -// displayContext(nodeType, appFromArg, 0); -// } -// }, -// }); -// }); +import { app } from '/scripts/app.js'; +import { displayContext } from './common.js'; +import type { ComfyNode } from './comfy/liteGraph.types.js'; +import { TLGraphNode } from './comfy/liteGraph.js'; +import { ComfyApp } from './comfy/typings/comfy.js'; + +const crystoolsExtensions: Record = { + 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', + 'Preview from image [Crystools]': 'Crystools.Image.PreviewFromImage', + 'Preview from metadata [Crystools]': 'Crystools.Image.PreviewFromMetadata', + 'Metadata comparator [Crystools]': 'Crystools.Metadata.MetadataComparator', + 'Stats system [Crystools]': 'Crystools.Utils.StatsSystem', + 'Show any to JSON [Crystools]': 'Crystools.Debugger.ConsoleAnyToJson', +}; + +Object.keys(crystoolsExtensions).forEach(key => { + app.registerExtension({ + name: crystoolsExtensions[key], + beforeRegisterNodeDef(nodeType: ComfyNode, nodeData: TLGraphNode, appFromArg: ComfyApp) { + if (nodeData.name === key) { + displayContext(nodeType, appFromArg, 0); + } + }, + }); +}); diff --git a/web/monitor.types.d.ts b/web/monitor.types.d.ts deleted file mode 100644 index 77d96cf..0000000 --- a/web/monitor.types.d.ts +++ /dev/null @@ -1,57 +0,0 @@ -type TGpuStatData = { - gpu_utilization: number, - gpu_temperature: number, - vram_total: number, - vram_used: number, - vram_used_percent: number, -} - -type TGpuSettings = { - utilization?: boolean, - vram?: boolean, - temperature?: boolean, -} - -type TGpuName = { - name: string, - index: number, -} - -type TStatsData = { - cpu_utilization: number, - device: string, - gpus: TGpuStatData[], - hdd_total: number, - hdd_used: number, - hdd_used_percent: number, - ram_total: number, - ram_used: number, - ram_used_percent: number, -} - -type TStatsSettings = { - rate?: number, - switchCPU?: boolean, - switchGPU?: boolean, - switchHDD?: boolean, - switchRAM?: boolean, - switchVRAM?: boolean, - whichHDD?: string, -} - -type TMonitorSettings = { - id: string, - name: string, - label: string, // on monitor - symbol: string, // on monitor - title?: string, // on monitor - tooltip?: string, // on settings - type: 'boolean' | 'number' | 'string', - defaultValue: boolean, - onChange: (value: boolean) => Promise, - htmlMonitorRef?: HTMLDivElement, - htmlMonitorSliderRef?: HTMLDivElement, - htmlMonitorLabelRef?: HTMLDivElement, - cssColor: string, - cssColorFinal?: string, -} diff --git a/web/progressBar.js b/web/progressBar.js index 89d086a..fba55e4 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -1,8 +1,7 @@ import { api } from '/scripts/api.js'; import { app } from '/scripts/app.js'; import { commonPrefix } from './common.js'; -import { ProgressBarUI } from './progressBarUI.js'; -import { EStatus } from './types.js'; +import { EStatus, ProgressBarUI } from './progressBarUI.js'; class CrystoolsProgressBar { constructor() { Object.defineProperty(this, "idExtensionName", { diff --git a/web/progressBar.ts b/web/progressBar.ts index 50a4f8f..9a38bb6 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -1,8 +1,7 @@ import { api } from '/scripts/api.js'; import { app } from '/scripts/app.js'; import { commonPrefix } from './common.js'; -import { ProgressBarUI } from './progressBarUI.js'; -import { EStatus } from './types.js'; +import { EStatus, ProgressBarUI } from './progressBarUI.js'; class CrystoolsProgressBar { idExtensionName = 'Crystools.progressBar'; diff --git a/web/progressBarUI.d.ts b/web/progressBarUI.d.ts index 694d0ef..800a9ce 100644 --- a/web/progressBarUI.d.ts +++ b/web/progressBarUI.d.ts @@ -1,4 +1,8 @@ -import { EStatus } from './types.js'; +export declare enum EStatus { + executing = "Executing", + executed = "Executed", + execution_error = "Execution error" +} export declare class ProgressBarUI { htmlIdCrystoolsRoot: string; htmlIdCrystoolsProgressBarContainer: string; diff --git a/web/progressBarUI.js b/web/progressBarUI.js index 5655187..714676f 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,5 +1,10 @@ import { app } from '/scripts/app.js'; -import { EStatus } from './types.js'; +export var EStatus; +(function (EStatus) { + EStatus["executing"] = "Executing"; + EStatus["executed"] = "Executed"; + EStatus["execution_error"] = "Execution error"; +})(EStatus || (EStatus = {})); export class ProgressBarUI { constructor(htmlIdCrystoolsRoot, htmlIdCrystoolsProgressBarContainer, centerNode) { Object.defineProperty(this, "htmlIdCrystoolsRoot", { diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index fee50b1..a2fc8f0 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -1,5 +1,10 @@ import { app } from '/scripts/app.js'; -import { EStatus } from './types.js'; + +export enum EStatus { + executing = 'Executing', + executed = 'Executed', + execution_error = 'Execution error', +} export class ProgressBarUI { htmlProgressSliderRef: HTMLDivElement; diff --git a/web/types.d.ts b/web/types.d.ts index 7682c24..2118c88 100644 --- a/web/types.d.ts +++ b/web/types.d.ts @@ -1,5 +1,58 @@ -export declare enum EStatus { - executing = "Executing", - executed = "Executed", - execution_error = "Execution error" + +type TGpuStatData = { + gpu_utilization: number, + gpu_temperature: number, + vram_total: number, + vram_used: number, + vram_used_percent: number, +} + +type TGpuSettings = { + utilization?: boolean, + vram?: boolean, + temperature?: boolean, +} + +type TGpuName = { + name: string, + index: number, +} + +type TStatsData = { + cpu_utilization: number, + device: string, + gpus: TGpuStatData[], + hdd_total: number, + hdd_used: number, + hdd_used_percent: number, + ram_total: number, + ram_used: number, + ram_used_percent: number, +} + +type TStatsSettings = { + rate?: number, + switchCPU?: boolean, + switchGPU?: boolean, + switchHDD?: boolean, + switchRAM?: boolean, + switchVRAM?: boolean, + whichHDD?: string, +} + +type TMonitorSettings = { + id: string, + name: string, + label: string, // on monitor + symbol: string, // on monitor + title?: string, // on monitor + tooltip?: string, // on settings + type: 'boolean' | 'number' | 'string', + defaultValue: boolean, + onChange: (value: boolean) => Promise, + htmlMonitorRef?: HTMLDivElement, + htmlMonitorSliderRef?: HTMLDivElement, + htmlMonitorLabelRef?: HTMLDivElement, + cssColor: string, + cssColorFinal?: string, } diff --git a/web/types.js b/web/types.js deleted file mode 100644 index acfb065..0000000 --- a/web/types.js +++ /dev/null @@ -1,6 +0,0 @@ -export var EStatus; -(function (EStatus) { - EStatus["executing"] = "Executing"; - EStatus["executed"] = "Executed"; - EStatus["execution_error"] = "Execution error"; -})(EStatus || (EStatus = {})); diff --git a/web/types.ts b/web/types.ts deleted file mode 100644 index e963d9b..0000000 --- a/web/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum EStatus { - executing = 'Executing', - executed = 'Executed', - execution_error = 'Execution error', -} From 752fc97c81df827c7290b172f19ac230cc2b8953 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 01:36:04 +0200 Subject: [PATCH 07/31] folder comfy2 --- .eslintrc.cjs | 2 +- web/comfy/scripts.d.ts | 3 +++ web/comfy/scripts.js | 3 +++ web/comfy/scripts.ts | 3 +++ web/common.js | 2 +- web/common.ts | 2 +- web/debugger.js | 4 +--- web/debugger.ts | 4 +--- web/extensions.js | 2 +- web/extensions.ts | 2 +- web/monitor.js | 3 +-- web/monitor.ts | 3 +-- web/monitorUI.js | 2 +- web/monitorUI.ts | 2 +- web/progressBar.js | 3 +-- web/progressBar.ts | 3 +-- web/progressBarUI.js | 2 +- web/progressBarUI.ts | 2 +- 18 files changed, 24 insertions(+), 23 deletions(-) create mode 100644 web/comfy/scripts.d.ts create mode 100644 web/comfy/scripts.js create mode 100644 web/comfy/scripts.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 2ae57ba..45660ae 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -61,7 +61,7 @@ module.exports = { "ObjectExpression": { "multiline": true, "minProperties": 1 }, "ObjectPattern": { "multiline": true, "minProperties": 1 }, "ImportDeclaration": {"multiline": true, "minProperties": 8 }, - "ExportDeclaration": { "multiline": true, "minProperties": 1 } + "ExportDeclaration": { "multiline": true, "minProperties": 8 } }], "@typescript-eslint/explicit-function-return-type": 'error', '@typescript-eslint/triple-slash-reference': 'off', diff --git a/web/comfy/scripts.d.ts b/web/comfy/scripts.d.ts new file mode 100644 index 0000000..884f898 --- /dev/null +++ b/web/comfy/scripts.d.ts @@ -0,0 +1,3 @@ +export { ComfyWidgets } from '/scripts/widgets.js'; +export { app } from '/scripts/app.js'; +export { api } from '/scripts/api.js'; diff --git a/web/comfy/scripts.js b/web/comfy/scripts.js new file mode 100644 index 0000000..884f898 --- /dev/null +++ b/web/comfy/scripts.js @@ -0,0 +1,3 @@ +export { ComfyWidgets } from '/scripts/widgets.js'; +export { app } from '/scripts/app.js'; +export { api } from '/scripts/api.js'; diff --git a/web/comfy/scripts.ts b/web/comfy/scripts.ts new file mode 100644 index 0000000..884f898 --- /dev/null +++ b/web/comfy/scripts.ts @@ -0,0 +1,3 @@ +export { ComfyWidgets } from '/scripts/widgets.js'; +export { app } from '/scripts/app.js'; +export { api } from '/scripts/api.js'; diff --git a/web/common.js b/web/common.js index 51d2dc8..5069947 100644 --- a/web/common.js +++ b/web/common.js @@ -1,4 +1,4 @@ -import { ComfyWidgets } from '/scripts/widgets.js'; +import { ComfyWidgets } from './comfy/scripts.js'; export const commonPrefix = '🪛'; export function displayContext(nodeType, appFromArg, index = 0, serialize_widgets = false, isVirtualNode = false) { function populate(text) { diff --git a/web/common.ts b/web/common.ts index c002713..1db2dd5 100644 --- a/web/common.ts +++ b/web/common.ts @@ -1,6 +1,6 @@ import type { TLGraphNode } from './comfy/liteGraph.js'; import { ComfyApp } from './comfy/typings/comfy.js'; -import { ComfyWidgets } from '/scripts/widgets.js'; +import { ComfyWidgets } from './comfy/scripts.js'; export const commonPrefix = '🪛'; diff --git a/web/debugger.js b/web/debugger.js index 70d954b..ea6c871 100644 --- a/web/debugger.js +++ b/web/debugger.js @@ -1,8 +1,6 @@ -import { app } from '/scripts/app.js'; -import { api } from '/scripts/api.js'; +import { app, api, ComfyWidgets } from './comfy/scripts.js'; import { commonPrefix, displayContext } from './common.js'; import { LiteGraph, TLGraphNode } from './comfy/liteGraph.js'; -import { ComfyWidgets } from '/scripts/widgets.js'; app.registerExtension({ name: 'Crystools.Debugger.ConsoleAny', beforeRegisterNodeDef(nodeType, nodeData, appFromArg) { diff --git a/web/debugger.ts b/web/debugger.ts index c518748..42ca280 100644 --- a/web/debugger.ts +++ b/web/debugger.ts @@ -1,10 +1,8 @@ -import { app } from '/scripts/app.js'; -import { api } from '/scripts/api.js'; +import { app, api, ComfyWidgets } from './comfy/scripts.js'; import { commonPrefix, displayContext } from './common.js'; import type { ComfyNode } from './comfy/liteGraph.js'; import { LiteGraph, TLGraphNode } from './comfy/liteGraph.js'; import { ComfyApp } from './comfy/typings/comfy.js'; -import { ComfyWidgets } from '/scripts/widgets.js'; // "Show any" Node app.registerExtension({ diff --git a/web/extensions.js b/web/extensions.js index 15a9f68..b14832d 100644 --- a/web/extensions.js +++ b/web/extensions.js @@ -1,4 +1,4 @@ -import { app } from '/scripts/app.js'; +import { app } from './comfy/scripts.js'; import { displayContext } from './common.js'; const crystoolsExtensions = { 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', diff --git a/web/extensions.ts b/web/extensions.ts index 1071ce6..80091ab 100644 --- a/web/extensions.ts +++ b/web/extensions.ts @@ -1,4 +1,4 @@ -import { app } from '/scripts/app.js'; +import { app } from './comfy/scripts.js'; import { displayContext } from './common.js'; import type { ComfyNode } from './comfy/liteGraph.types.js'; import { TLGraphNode } from './comfy/liteGraph.js'; diff --git a/web/monitor.js b/web/monitor.js index f8c1d2d..aef8571 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1,5 +1,4 @@ -import { app } from '/scripts/app.js'; -import { api } from '/scripts/api.js'; +import { app, api } from './comfy/scripts.js'; import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; class CrystoolsMonitor { diff --git a/web/monitor.ts b/web/monitor.ts index 22333c6..b3bf4c8 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,5 +1,4 @@ -import { app } from '/scripts/app.js'; -import { api } from '/scripts/api.js'; +import { app, api } from './comfy/scripts.js'; import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; diff --git a/web/monitorUI.js b/web/monitorUI.js index 59ddbf2..e277177 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,4 +1,4 @@ -import { app } from '/scripts/app.js'; +import { app } from './comfy/scripts.js'; export class MonitorUI { constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { Object.defineProperty(this, "monitorCPUElement", { diff --git a/web/monitorUI.ts b/web/monitorUI.ts index ef647f8..82fc687 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -1,4 +1,4 @@ -import { app } from '/scripts/app.js'; +import { app } from './comfy/scripts.js'; export class MonitorUI { htmlIdCrystoolsRoot = 'crystools-root'; diff --git a/web/progressBar.js b/web/progressBar.js index fba55e4..737e746 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -1,5 +1,4 @@ -import { api } from '/scripts/api.js'; -import { app } from '/scripts/app.js'; +import { app, api } from './comfy/scripts.js'; import { commonPrefix } from './common.js'; import { EStatus, ProgressBarUI } from './progressBarUI.js'; class CrystoolsProgressBar { diff --git a/web/progressBar.ts b/web/progressBar.ts index 9a38bb6..5aeaff7 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -1,5 +1,4 @@ -import { api } from '/scripts/api.js'; -import { app } from '/scripts/app.js'; +import { app, api } from './comfy/scripts.js'; import { commonPrefix } from './common.js'; import { EStatus, ProgressBarUI } from './progressBarUI.js'; diff --git a/web/progressBarUI.js b/web/progressBarUI.js index 714676f..6809e34 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,4 +1,4 @@ -import { app } from '/scripts/app.js'; +import { app } from './comfy/scripts.js'; export var EStatus; (function (EStatus) { EStatus["executing"] = "Executing"; diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index a2fc8f0..f1bde93 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -1,4 +1,4 @@ -import { app } from '/scripts/app.js'; +import { app } from './comfy/scripts.js'; export enum EStatus { executing = 'Executing', From f4703939d6a951f77ecf7ac6b68d21013baf25d5 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 01:51:55 +0200 Subject: [PATCH 08/31] folder comfy3 --- web/comfy/index.d.ts | 5 +++++ web/comfy/index.js | 2 ++ web/comfy/index.ts | 5 +++++ web/comfy/liteGraph.ts | 1 - web/comfy/liteGraph.types.d.ts | 5 ----- web/common.d.ts | 4 ++-- web/common.js | 2 +- web/common.ts | 5 ++--- web/debugger.js | 3 +-- web/debugger.ts | 6 ++---- web/extensions.js | 2 +- web/extensions.ts | 6 ++---- web/monitor.js | 2 +- web/monitor.ts | 2 +- web/monitorUI.js | 2 +- web/monitorUI.ts | 2 +- web/progressBar.js | 2 +- web/progressBar.ts | 2 +- web/progressBarUI.js | 2 +- web/progressBarUI.ts | 2 +- 20 files changed, 31 insertions(+), 31 deletions(-) create mode 100644 web/comfy/index.d.ts create mode 100644 web/comfy/index.js create mode 100644 web/comfy/index.ts diff --git a/web/comfy/index.d.ts b/web/comfy/index.d.ts new file mode 100644 index 0000000..8239551 --- /dev/null +++ b/web/comfy/index.d.ts @@ -0,0 +1,5 @@ +export type * from './scripts.js'; +export * from './scripts.js'; +export type { ComfyApp } from './typings/comfy.js'; +export * from './liteGraph.js'; +export type * from './liteGraph.js'; diff --git a/web/comfy/index.js b/web/comfy/index.js new file mode 100644 index 0000000..e364fb0 --- /dev/null +++ b/web/comfy/index.js @@ -0,0 +1,2 @@ +export * from './scripts.js'; +export * from './liteGraph.js'; diff --git a/web/comfy/index.ts b/web/comfy/index.ts new file mode 100644 index 0000000..8239551 --- /dev/null +++ b/web/comfy/index.ts @@ -0,0 +1,5 @@ +export type * from './scripts.js'; +export * from './scripts.js'; +export type { ComfyApp } from './typings/comfy.js'; +export * from './liteGraph.js'; +export type * from './liteGraph.js'; diff --git a/web/comfy/liteGraph.ts b/web/comfy/liteGraph.ts index f9785f6..d3a6787 100644 --- a/web/comfy/liteGraph.ts +++ b/web/comfy/liteGraph.ts @@ -1,7 +1,6 @@ // / // A LOTS OF PATCHES FOR LITEGRAPH TYPES ¯\_(ツ)_/¯ export type * from './liteGraph.types.js'; -// export * from './liteGraph.types'; export * from '/scripts/widgets.js'; import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types.js'; diff --git a/web/comfy/liteGraph.types.d.ts b/web/comfy/liteGraph.types.d.ts index 2ac3ab3..0281a91 100644 --- a/web/comfy/liteGraph.types.d.ts +++ b/web/comfy/liteGraph.types.d.ts @@ -2,11 +2,6 @@ import { LGraph } from './typings/litegraph.js'; export type * from './typings/litegraph.js'; -// export type * from 'scripts/widgets'; -// export type * from 'scripts/app'; -// export type { api } from 'scripts/api'; -// -// import { LGraph, LiteGraph } from '/types/litegraph'; export declare type TypeLiteGraph = typeof LiteGraph & { graph: LGraph; diff --git a/web/common.d.ts b/web/common.d.ts index a7605e0..6c4101a 100644 --- a/web/common.d.ts +++ b/web/common.d.ts @@ -1,4 +1,4 @@ -import type { TLGraphNode } from './comfy/liteGraph.js'; -import { ComfyApp } from './comfy/typings/comfy.js'; +import type { TLGraphNode } from './comfy/index.js'; +import { ComfyApp } from './comfy/index.js'; export declare const commonPrefix = "\uD83E\uDE9B"; export declare function displayContext(nodeType: TLGraphNode, appFromArg: ComfyApp, index?: number, serialize_widgets?: boolean, isVirtualNode?: boolean): void; diff --git a/web/common.js b/web/common.js index 5069947..a54e998 100644 --- a/web/common.js +++ b/web/common.js @@ -1,4 +1,4 @@ -import { ComfyWidgets } from './comfy/scripts.js'; +import { ComfyWidgets } from './comfy/index.js'; export const commonPrefix = '🪛'; export function displayContext(nodeType, appFromArg, index = 0, serialize_widgets = false, isVirtualNode = false) { function populate(text) { diff --git a/web/common.ts b/web/common.ts index 1db2dd5..09bd981 100644 --- a/web/common.ts +++ b/web/common.ts @@ -1,6 +1,5 @@ -import type { TLGraphNode } from './comfy/liteGraph.js'; -import { ComfyApp } from './comfy/typings/comfy.js'; -import { ComfyWidgets } from './comfy/scripts.js'; +import type { TLGraphNode } from './comfy/index.js'; +import { ComfyWidgets, ComfyApp } from './comfy/index.js'; export const commonPrefix = '🪛'; diff --git a/web/debugger.js b/web/debugger.js index ea6c871..ecc060f 100644 --- a/web/debugger.js +++ b/web/debugger.js @@ -1,6 +1,5 @@ -import { app, api, ComfyWidgets } from './comfy/scripts.js'; +import { app, api, ComfyWidgets, LiteGraph, TLGraphNode } from './comfy/index.js'; import { commonPrefix, displayContext } from './common.js'; -import { LiteGraph, TLGraphNode } from './comfy/liteGraph.js'; app.registerExtension({ name: 'Crystools.Debugger.ConsoleAny', beforeRegisterNodeDef(nodeType, nodeData, appFromArg) { diff --git a/web/debugger.ts b/web/debugger.ts index 42ca280..26faa54 100644 --- a/web/debugger.ts +++ b/web/debugger.ts @@ -1,8 +1,6 @@ -import { app, api, ComfyWidgets } from './comfy/scripts.js'; +import type { ComfyNode } from './comfy/index.js'; +import { app, api, ComfyWidgets, LiteGraph, TLGraphNode, ComfyApp } from './comfy/index.js'; import { commonPrefix, displayContext } from './common.js'; -import type { ComfyNode } from './comfy/liteGraph.js'; -import { LiteGraph, TLGraphNode } from './comfy/liteGraph.js'; -import { ComfyApp } from './comfy/typings/comfy.js'; // "Show any" Node app.registerExtension({ diff --git a/web/extensions.js b/web/extensions.js index b14832d..62e0981 100644 --- a/web/extensions.js +++ b/web/extensions.js @@ -1,4 +1,4 @@ -import { app } from './comfy/scripts.js'; +import { app } from './comfy/index.js'; import { displayContext } from './common.js'; const crystoolsExtensions = { 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', diff --git a/web/extensions.ts b/web/extensions.ts index 80091ab..f5fbc08 100644 --- a/web/extensions.ts +++ b/web/extensions.ts @@ -1,8 +1,6 @@ -import { app } from './comfy/scripts.js'; +import { app, TLGraphNode, ComfyApp } from './comfy/index.js'; +import type { ComfyNode } from './comfy/index.js'; import { displayContext } from './common.js'; -import type { ComfyNode } from './comfy/liteGraph.types.js'; -import { TLGraphNode } from './comfy/liteGraph.js'; -import { ComfyApp } from './comfy/typings/comfy.js'; const crystoolsExtensions: Record = { 'Get resolution [Crystools]': 'Crystools.Image.GetResolution', diff --git a/web/monitor.js b/web/monitor.js index aef8571..d9655f8 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1,4 +1,4 @@ -import { app, api } from './comfy/scripts.js'; +import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; class CrystoolsMonitor { diff --git a/web/monitor.ts b/web/monitor.ts index b3bf4c8..f51b721 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,4 +1,4 @@ -import { app, api } from './comfy/scripts.js'; +import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; diff --git a/web/monitorUI.js b/web/monitorUI.js index e277177..51f8148 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,4 +1,4 @@ -import { app } from './comfy/scripts.js'; +import { app } from './comfy/index.js'; export class MonitorUI { constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { Object.defineProperty(this, "monitorCPUElement", { diff --git a/web/monitorUI.ts b/web/monitorUI.ts index 82fc687..716e93a 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -1,4 +1,4 @@ -import { app } from './comfy/scripts.js'; +import { app } from './comfy/index.js'; export class MonitorUI { htmlIdCrystoolsRoot = 'crystools-root'; diff --git a/web/progressBar.js b/web/progressBar.js index 737e746..3a032a7 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -1,4 +1,4 @@ -import { app, api } from './comfy/scripts.js'; +import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; import { EStatus, ProgressBarUI } from './progressBarUI.js'; class CrystoolsProgressBar { diff --git a/web/progressBar.ts b/web/progressBar.ts index 5aeaff7..9ae4b8c 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -1,4 +1,4 @@ -import { app, api } from './comfy/scripts.js'; +import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; import { EStatus, ProgressBarUI } from './progressBarUI.js'; diff --git a/web/progressBarUI.js b/web/progressBarUI.js index 6809e34..d7f46f2 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,4 +1,4 @@ -import { app } from './comfy/scripts.js'; +import { app } from './comfy/index.js'; export var EStatus; (function (EStatus) { EStatus["executing"] = "Executing"; diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index f1bde93..04cf81f 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -1,4 +1,4 @@ -import { app } from './comfy/scripts.js'; +import { app } from './comfy/index.js'; export enum EStatus { executing = 'Executing', From 3ef9276c97a747d080ad8e388d2f2aab65998852 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 12:36:17 +0200 Subject: [PATCH 09/31] cleaning --- tsconfig.json | 21 +++++++-------------- web/comfy/liteGraph.d.ts | 1 - web/comfy/liteGraph.js | 1 - web/comfy/liteGraph.ts | 1 - web/comfy/scripts.d.ts | 6 +++--- web/comfy/scripts.js | 6 +++--- web/comfy/scripts.ts | 9 ++++++--- 7 files changed, 19 insertions(+), 26 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index ca96d32..8ccd4eb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,23 +6,15 @@ "typeRoots": [ // "./web/ts/typings", ], -// "rootDir": "../../web", - "baseUrl": "./", +// "rootDir": "../", + "baseUrl": "../../web", +// "baseUrl": "./", "paths": { - "/scripts/*": ["../../web/scripts/*"], // works -// "scripts/*": ["scripts/*"], // works -// "scripts/*": ["../../web/scripts/*"], // works -// "web/*": ["web/*"], // works -// "/lib/*": ["../../web/lib/*"], -// "extensions/*": ["../../web/extensions/*"], -// "types/*": ["web/types/*"] +// "/scripts/*": ["../../web/scripts/*"], // works }, - // "rootDir": "./web/src", "rootDirs": [ -// "../../web/scripts", -// "../../web", - "web" -// "../../web" + "../../web", +// "web" ], "preserveSymlinks": true, "checkJs": false, @@ -64,6 +56,7 @@ }, "include": [ // "./custom_nodes/ComfyUI-Crystools/web/*.ts", +// "../../../web/*.ts", // "../../web/*.ts", "web/*.ts", // "web/types.d.ts" diff --git a/web/comfy/liteGraph.d.ts b/web/comfy/liteGraph.d.ts index 460b065..52ecb7e 100644 --- a/web/comfy/liteGraph.d.ts +++ b/web/comfy/liteGraph.d.ts @@ -1,5 +1,4 @@ export type * from './liteGraph.types.js'; -export * from '/scripts/widgets.js'; import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types.js'; declare const LGraphNode: typeof TypeGraphNode; export interface IWidget extends IWidgetOld { diff --git a/web/comfy/liteGraph.js b/web/comfy/liteGraph.js index bc661ca..38d7b92 100644 --- a/web/comfy/liteGraph.js +++ b/web/comfy/liteGraph.js @@ -1,4 +1,3 @@ -export * from '/scripts/widgets.js'; export class TLGraphNode extends LGraphNode { constructor() { super(...arguments); diff --git a/web/comfy/liteGraph.ts b/web/comfy/liteGraph.ts index d3a6787..e2d4689 100644 --- a/web/comfy/liteGraph.ts +++ b/web/comfy/liteGraph.ts @@ -1,7 +1,6 @@ // / // A LOTS OF PATCHES FOR LITEGRAPH TYPES ¯\_(ツ)_/¯ export type * from './liteGraph.types.js'; -export * from '/scripts/widgets.js'; import type { IWidget as IWidgetOld, LGraphNode as TypeGraphNode, TypeLiteGraph } from './liteGraph.types.js'; diff --git a/web/comfy/scripts.d.ts b/web/comfy/scripts.d.ts index 884f898..c979c77 100644 --- a/web/comfy/scripts.d.ts +++ b/web/comfy/scripts.d.ts @@ -1,3 +1,3 @@ -export { ComfyWidgets } from '/scripts/widgets.js'; -export { app } from '/scripts/app.js'; -export { api } from '/scripts/api.js'; +export { ComfyWidgets } from '../../../scripts/widgets.js'; +export { app } from '../../../scripts/app.js'; +export { api } from '../../../scripts/api.js'; diff --git a/web/comfy/scripts.js b/web/comfy/scripts.js index 884f898..c979c77 100644 --- a/web/comfy/scripts.js +++ b/web/comfy/scripts.js @@ -1,3 +1,3 @@ -export { ComfyWidgets } from '/scripts/widgets.js'; -export { app } from '/scripts/app.js'; -export { api } from '/scripts/api.js'; +export { ComfyWidgets } from '../../../scripts/widgets.js'; +export { app } from '../../../scripts/app.js'; +export { api } from '../../../scripts/api.js'; diff --git a/web/comfy/scripts.ts b/web/comfy/scripts.ts index 884f898..9179bbd 100644 --- a/web/comfy/scripts.ts +++ b/web/comfy/scripts.ts @@ -1,3 +1,6 @@ -export { ComfyWidgets } from '/scripts/widgets.js'; -export { app } from '/scripts/app.js'; -export { api } from '/scripts/api.js'; +// @ts-expect-error I could not find a way to make this work +export { ComfyWidgets } from '../../../scripts/widgets.js'; +// @ts-expect-error I could not find a way to make this work +export { app } from '../../../scripts/app.js'; +// @ts-expect-error I could not find a way to make this work +export { api } from '../../../scripts/api.js'; From 1a34aee8d95785930547025d481f8141d6556063 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 14:27:47 +0200 Subject: [PATCH 10/31] menu fixed --- web/monitor.js | 246 ++++++++++++++++++++++----------------------- web/monitor.ts | 230 ++++++++++++++++++++++-------------------- web/progressBar.js | 4 +- web/progressBar.ts | 4 +- web/styles.d.ts | 12 +++ web/styles.js | 14 +++ web/styles.ts | 13 +++ web/types.d.ts | 1 + web/utils.d.ts | 3 + web/utils.js | 40 ++++++++ web/utils.ts | 45 +++++++++ 11 files changed, 377 insertions(+), 235 deletions(-) create mode 100644 web/styles.d.ts create mode 100644 web/styles.js create mode 100644 web/styles.ts create mode 100644 web/utils.d.ts create mode 100644 web/utils.js create mode 100644 web/utils.ts diff --git a/web/monitor.js b/web/monitor.js index d9655f8..f714ba6 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1,6 +1,8 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; +import { Colors } from './styles.js'; +import { convertNumberToPascalCase } from './utils.js'; class CrystoolsMonitor { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -21,30 +23,6 @@ class CrystoolsMonitor { writable: true, value: void 0 }); - Object.defineProperty(this, "idInputRate", { - enumerable: true, - configurable: true, - writable: true, - value: 'Crystools.inputRate' - }); - Object.defineProperty(this, "defaultRate", { - enumerable: true, - configurable: true, - writable: true, - value: .5 - }); - Object.defineProperty(this, "idWhichHDD", { - enumerable: true, - configurable: true, - writable: true, - value: 'Crystools.whichHDD' - }); - Object.defineProperty(this, "defaultWhichHDD", { - enumerable: true, - configurable: true, - writable: true, - value: '/' - }); Object.defineProperty(this, "monitorGPUSettings", { enumerable: true, configurable: true, @@ -63,13 +41,75 @@ class CrystoolsMonitor { writable: true, value: [] }); + Object.defineProperty(this, "settingsRate", { + enumerable: true, + configurable: true, + writable: true, + value: { + id: 'Crystools.RefreshRate', + name: this.menuPrefix + 'Refresh per second', + tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', + type: 'slider', + attrs: { + min: 0, + max: 2, + step: 0.25, + }, + defaultValue: .5, + onChange: async (value) => { + let valueNumber; + try { + valueNumber = parseFloat(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } + catch (error) { + console.error(error); + return; + } + try { + await this.updateServer({ + rate: valueNumber, + }); + } + catch (error) { + console.error(error); + return; + } + if (valueNumber === 0) { + this.monitorUI.updateAllMonitors({ + cpu_utilization: 0, + device: 'cpu', + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }); + } + this.monitorUI?.updateAllAnimationDuration(valueNumber); + }, + } + }); Object.defineProperty(this, "monitorCPUElement", { enumerable: true, configurable: true, writable: true, value: { - id: 'Crystools.switchCPU', - name: this.menuPrefix + ' [monitor] CPU Usage', + id: 'Crystools.ShowCpu', + name: this.menuPrefix + ' CPU Usage', + category: ['Crystools', 'Hardware', 'Cpu'], type: 'boolean', label: 'CPU', symbol: '%', @@ -77,7 +117,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#0AA015', + cssColor: Colors.CPU, onChange: async (value) => { this.monitorUI?.updateWidget(this.monitorCPUElement); await this.updateServer({ @@ -91,8 +131,9 @@ class CrystoolsMonitor { configurable: true, writable: true, value: { - id: 'Crystools.switchRAM', - name: this.menuPrefix + ' [monitor] RAM Used', + id: 'Crystools.ShowRam', + name: this.menuPrefix + ' RAM Used', + category: ['Crystools', 'Hardware', 'Ram'], type: 'boolean', label: 'RAM', symbol: '%', @@ -100,7 +141,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#07630D', + cssColor: Colors.RAM, onChange: async (value) => { this.monitorUI?.updateWidget(this.monitorRAMElement); await this.updateServer({ @@ -114,17 +155,17 @@ class CrystoolsMonitor { configurable: true, writable: true, value: { - id: 'Crystools.switchHDD', - name: this.menuPrefix + ' [monitor] HDD Used', + id: 'Crystools.ShowHdd', + name: this.menuPrefix + ' Show HDD Used', + category: ['Crystools', 'Show Hard Disk', 'Show'], type: 'boolean', label: 'HDD', symbol: '%', - tooltip: 'See Partition to show (HDD)', - defaultValue: true, + defaultValue: false, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#730F92', + cssColor: Colors.DISK, onChange: async (value) => { this.monitorUI?.updateWidget(this.monitorHDDElement); await this.updateServer({ @@ -133,89 +174,45 @@ class CrystoolsMonitor { }, } }); + Object.defineProperty(this, "settingsHDD", { + enumerable: true, + configurable: true, + writable: true, + value: { + id: 'Crystools.WhichHdd', + name: this.menuPrefix + ' Partition to show', + category: ['Crystools', 'Show Hard Disk', 'Which'], + type: 'combo', + defaultValue: '/', + data: [], + options: (value) => { + const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); + return this.settingsHDD.data.map((m) => ({ + value: m, + text: m, + selected: !value ? m === which : m === value, + })); + }, + onChange: async (value) => { + await this.updateServer({ + whichHDD: value, + }); + }, + } + }); Object.defineProperty(this, "createSettings", { enumerable: true, configurable: true, writable: true, value: () => { - app.ui.settings.addSetting(this.monitorCPUElement); + app.ui.settings.addSetting(this.settingsRate); app.ui.settings.addSetting(this.monitorRAMElement); - app.ui.settings.addSetting(this.monitorHDDElement); - app.ui.settings.addSetting({ - id: this.idInputRate, - name: this.menuPrefix + '[monitor] Refresh rate', - tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', - type: 'slider', - attrs: { - min: 0, - max: 5, - step: 0.25, - }, - defaultValue: this.defaultRate, - onChange: async (value) => { - let valueNumber; - try { - valueNumber = parseFloat(value); - if (isNaN(valueNumber)) { - throw new Error('invalid value'); - } - } - catch (error) { - console.error(error); - return; - } - try { - await this.updateServer({ - rate: valueNumber, - }); - } - catch (error) { - console.error(error); - return; - } - if (valueNumber === 0) { - this.monitorUI.updateAllMonitors({ - cpu_utilization: 0, - device: 'cpu', - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); - } - this.monitorUI?.updateAllAnimationDuration(valueNumber); - }, - }); + app.ui.settings.addSetting(this.monitorCPUElement); void this.getHDDsFromServer().then((data) => { - const which = app.ui.settings.getSettingValue(this.idWhichHDD, this.defaultWhichHDD); - app.ui.settings.addSetting({ - id: this.idWhichHDD, - name: this.menuPrefix + '[monitor] Partition to show', - type: 'combo', - defaultValue: this.defaultWhichHDD, - options: (value) => data.map((m) => ({ - value: m, - text: m, - selected: !value ? m === which : m === value, - })), - onChange: async (value) => { - await this.updateServer({ - whichHDD: value, - }); - }, - }); + this.settingsHDD.data = data; + app.ui.settings.addSetting(this.settingsHDD); }); + app.ui.settings.addSetting(this.monitorHDDElement); void this.getGPUsFromServer().then((gpus) => { let moreThanOneGPU = false; if (gpus.length > 1) { @@ -235,8 +232,9 @@ class CrystoolsMonitor { labelTemperature = 'Temp ' + index; } const monitorGPUNElement = { - id: 'Crystools.switchGPU' + index, - name: this.menuPrefix + `[menu] Display GPU\r\n[${index}] ${name}`, + id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), + category: ['Crystools', `Show GPU [${index}] ${name}`, 'Usage'], + name: this.menuPrefix + ' Usage', type: 'boolean', label, symbol: '%', @@ -245,7 +243,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#0C86F4', + cssColor: Colors.GPU, onChange: async (value) => { this.monitorUI?.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index, { @@ -254,8 +252,9 @@ class CrystoolsMonitor { }, }; const monitorVRAMNElement = { - id: 'Crystools.switchVRAM' + index, - name: this.menuPrefix + `[menu] Display GPU VRAM\r\n[${index}] ${name}`, + id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), + category: ['Crystools', `Show GPU [${index}] ${name}`, 'VRAM'], + name: this.menuPrefix + ' VRAM', type: 'boolean', label: labelVRAM, symbol: '%', @@ -264,7 +263,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#176EC7', + cssColor: Colors.VRAM, onChange: async (value) => { this.monitorUI?.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index, { @@ -273,8 +272,9 @@ class CrystoolsMonitor { }, }; const monitorTemperatureNElement = { - id: 'Crystools.switchTemperature' + index, - name: this.menuPrefix + `[menu] Display GPU Temperature\r\n[${index}] ${name}`, + id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), + category: ['Crystools', `Show GPU [${index}] ${name}`, 'Temperature'], + name: this.menuPrefix + ' Temperature', type: 'boolean', label: labelTemperature, symbol: '°', @@ -283,8 +283,8 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#00ff00', - cssColorFinal: '#ff0000', + cssColor: Colors.TEMP_START, + cssColorFinal: Colors.TEMP_END, onChange: async (value) => { this.monitorUI?.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index, { @@ -295,9 +295,9 @@ class CrystoolsMonitor { this.monitorGPUSettings[index] = monitorGPUNElement; this.monitorVRAMSettings[index] = monitorVRAMNElement; this.monitorTemperatureSettings[index] = monitorTemperatureNElement; - app.ui.settings.addSetting(this.monitorGPUSettings[index]); - app.ui.settings.addSetting(this.monitorVRAMSettings[index]); app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); + app.ui.settings.addSetting(this.monitorVRAMSettings[index]); + app.ui.settings.addSetting(this.monitorGPUSettings[index]); }); }); } @@ -381,7 +381,7 @@ class CrystoolsMonitor { this.createSettings(); } setup() { - const currentRate = parseFloat(app.ui.settings.getSettingValue(this.idInputRate, this.defaultRate)); + const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate); this.registerListeners(); } diff --git a/web/monitor.ts b/web/monitor.ts index f51b721..6e23dd3 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,6 +1,8 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; +import { Colors } from './styles.js'; +import { convertNumberToPascalCase } from './utils.js'; class CrystoolsMonitor { idExtensionName = 'Crystools.monitor'; @@ -8,18 +10,75 @@ class CrystoolsMonitor { monitorUI: MonitorUI; - idInputRate = 'Crystools.inputRate'; - defaultRate = .5; - idWhichHDD = 'Crystools.whichHDD'; - defaultWhichHDD = '/'; monitorGPUSettings: TMonitorSettings[] = []; monitorVRAMSettings: TMonitorSettings[] = []; monitorTemperatureSettings: TMonitorSettings[] = []; + settingsRate = { + id: 'Crystools.RefreshRate', + name: this.menuPrefix + 'Refresh per second', + tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', + type: 'slider', + attrs: { + min: 0, + max: 2, + step: 0.25, + }, + defaultValue: .5, + onChange: async(value: string): Promise => { + let valueNumber: number; + + try { + valueNumber = parseFloat(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } catch (error) { + console.error(error); + return; + } + try { + await this.updateServer({ + rate: valueNumber, + }); + } catch (error) { + console.error(error); + return; + } + + if (valueNumber === 0) { + this.monitorUI.updateAllMonitors({ + cpu_utilization: 0, + device: 'cpu', + + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }); + } + + this.monitorUI?.updateAllAnimationDuration(valueNumber); + }, + }; + + // CPU Variables monitorCPUElement: TMonitorSettings = { - id: 'Crystools.switchCPU', - name: this.menuPrefix + ' [monitor] CPU Usage', + id: 'Crystools.ShowCpu', + name: this.menuPrefix + ' CPU Usage', + category: ['Crystools', 'Hardware', 'Cpu' ], type: 'boolean', label: 'CPU', symbol: '%', @@ -27,7 +86,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#0AA015', + cssColor: Colors.CPU, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(this.monitorCPUElement); await this.updateServer({ @@ -38,8 +97,9 @@ class CrystoolsMonitor { // RAM Variables monitorRAMElement: TMonitorSettings = { - id: 'Crystools.switchRAM', - name: this.menuPrefix + ' [monitor] RAM Used', + id: 'Crystools.ShowRam', + name: this.menuPrefix + ' RAM Used', + category: ['Crystools', 'Hardware', 'Ram' ], type: 'boolean', label: 'RAM', symbol: '%', @@ -47,7 +107,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#07630D', + cssColor: Colors.RAM, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(this.monitorRAMElement); await this.updateServer({ @@ -58,17 +118,18 @@ class CrystoolsMonitor { // HDD Variables monitorHDDElement: TMonitorSettings = { - id: 'Crystools.switchHDD', - name: this.menuPrefix + ' [monitor] HDD Used', + id: 'Crystools.ShowHdd', + name: this.menuPrefix + ' Show HDD Used', + category: ['Crystools', 'Show Hard Disk', 'Show' ], type: 'boolean', label: 'HDD', symbol: '%', - tooltip: 'See Partition to show (HDD)', - defaultValue: true, + // tooltip: 'See Partition to show (HDD)', + defaultValue: false, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#730F92', + cssColor: Colors.DISK, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(this.monitorHDDElement); await this.updateServer({ @@ -77,95 +138,44 @@ class CrystoolsMonitor { }, }; + settingsHDD = { + id: 'Crystools.WhichHdd', + name: this.menuPrefix + ' Partition to show', + category: ['Crystools', 'Show Hard Disk', 'Which' ], + type: 'combo', + defaultValue: '/', + data: [], + // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? + options: (value: string): any => { + const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); + return this.settingsHDD.data.map((m) => ({ + value: m, + text: m, + selected: !value ? m === which : m === value, + })); + }, + onChange: async(value: string): Promise => { + await this.updateServer({ + whichHDD: value, + }); + }, + }; + constructor() { this.createSettings(); } createSettings = (): void => { - app.ui.settings.addSetting(this.monitorCPUElement); + app.ui.settings.addSetting(this.settingsRate); app.ui.settings.addSetting(this.monitorRAMElement); - app.ui.settings.addSetting(this.monitorHDDElement); - - app.ui.settings.addSetting({ - id: this.idInputRate, - name: this.menuPrefix + '[monitor] Refresh rate', - tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', - type: 'slider', - attrs: { - min: 0, - max: 5, - step: 0.25, - }, - defaultValue: this.defaultRate, - onChange: async(value: string) => { - let valueNumber: number; - - try { - valueNumber = parseFloat(value); - if (isNaN(valueNumber)) { - throw new Error('invalid value'); - } - } catch (error) { - console.error(error); - return; - } - try { - await this.updateServer({ - rate: valueNumber, - }); - } catch (error) { - console.error(error); - return; - } - - if (valueNumber === 0) { - this.monitorUI.updateAllMonitors({ - cpu_utilization: 0, - device: 'cpu', - - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); - } - - this.monitorUI?.updateAllAnimationDuration(valueNumber); - }, - }); + app.ui.settings.addSetting(this.monitorCPUElement); void this.getHDDsFromServer().then((data: string[]): void => { - const which = app.ui.settings.getSettingValue(this.idWhichHDD, this.defaultWhichHDD); - app.ui.settings.addSetting({ - id: this.idWhichHDD, - name: this.menuPrefix + '[monitor] Partition to show', - type: 'combo', - defaultValue: this.defaultWhichHDD, - // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? - options: (value: string) => - data.map((m) => ({ - value: m, - text: m, - selected: !value ? m === which : m === value, - })), - onChange: async(value: string) => { - await this.updateServer({ - whichHDD: value, - }); - }, - }); + // @ts-ignore + this.settingsHDD.data = data; + app.ui.settings.addSetting(this.settingsHDD); }); + app.ui.settings.addSetting(this.monitorHDDElement); void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { let moreThanOneGPU = false; @@ -193,8 +203,9 @@ class CrystoolsMonitor { // GPU Utilization Variables const monitorGPUNElement: TMonitorSettings = { - id: 'Crystools.switchGPU' + index, - name: this.menuPrefix + `[menu] Display GPU\r\n[${index}] ${name}`, + id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), + category: ['Crystools', `Show GPU [${index}] ${name}`, 'Usage' ], + name: this.menuPrefix + ' Usage', type: 'boolean', label, symbol: '%', @@ -203,7 +214,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#0C86F4', + cssColor: Colors.GPU, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index,{ @@ -214,8 +225,9 @@ class CrystoolsMonitor { // GPU VRAM Variables const monitorVRAMNElement: TMonitorSettings = { - id: 'Crystools.switchVRAM' + index, - name: this.menuPrefix + `[menu] Display GPU VRAM\r\n[${index}] ${name}`, + id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), + category: ['Crystools', `Show GPU [${index}] ${name}`, 'VRAM' ], + name: this.menuPrefix + ' VRAM', type: 'boolean', label: labelVRAM, symbol: '%', @@ -224,7 +236,7 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#176EC7', + cssColor: Colors.VRAM, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index,{ @@ -235,8 +247,9 @@ class CrystoolsMonitor { // GPU Temperature Variables const monitorTemperatureNElement: TMonitorSettings = { - id: 'Crystools.switchTemperature' + index, - name: this.menuPrefix + `[menu] Display GPU Temperature\r\n[${index}] ${name}`, + id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), + category: ['Crystools', `Show GPU [${index}] ${name}`, 'Temperature' ], + name: this.menuPrefix + ' Temperature', type: 'boolean', label: labelTemperature, symbol: '°', @@ -245,8 +258,8 @@ class CrystoolsMonitor { htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, htmlMonitorLabelRef: undefined, - cssColor: '#00ff00', - cssColorFinal: '#ff0000', + cssColor: Colors.TEMP_START, + cssColorFinal: Colors.TEMP_END, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index,{ @@ -259,11 +272,11 @@ class CrystoolsMonitor { this.monitorVRAMSettings[index] = monitorVRAMNElement; this.monitorTemperatureSettings[index] = monitorTemperatureNElement; // @ts-ignore - app.ui.settings.addSetting(this.monitorGPUSettings[index]); + app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); // @ts-ignore app.ui.settings.addSetting(this.monitorVRAMSettings[index]); // @ts-ignore - app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); + app.ui.settings.addSetting(this.monitorGPUSettings[index]); }); }); }; @@ -312,7 +325,8 @@ class CrystoolsMonitor { }; setup(): void { - const currentRate = parseFloat(app.ui.settings.getSettingValue(this.idInputRate, this.defaultRate)); + const currentRate = + parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); this.monitorUI = new MonitorUI( this.monitorCPUElement, diff --git a/web/progressBar.js b/web/progressBar.js index 3a032a7..59e1737 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -13,7 +13,7 @@ class CrystoolsProgressBar { enumerable: true, configurable: true, writable: true, - value: 'Crystools.showStatus' + value: 'Crystools.ProgressBar' }); Object.defineProperty(this, "defaultShowStatus", { enumerable: true, @@ -88,7 +88,7 @@ class CrystoolsProgressBar { value: () => { app.ui.settings.addSetting({ id: this.idShowProgressBar, - name: this.menuPrefix + '[monitor] Show progress bar', + name: this.menuPrefix + ' Progress bar', type: 'boolean', defaultValue: this.defaultShowStatus, onChange: this.showProgressBar, diff --git a/web/progressBar.ts b/web/progressBar.ts index 9ae4b8c..0951a96 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -4,7 +4,7 @@ import { EStatus, ProgressBarUI } from './progressBarUI.js'; class CrystoolsProgressBar { idExtensionName = 'Crystools.progressBar'; - idShowProgressBar = 'Crystools.showStatus'; + idShowProgressBar = 'Crystools.ProgressBar'; defaultShowStatus = true; menuPrefix = commonPrefix; htmlIdCrystoolsRoot = 'crystools-root'; @@ -28,7 +28,7 @@ class CrystoolsProgressBar { createSettings = (): void => { app.ui.settings.addSetting({ id: this.idShowProgressBar, - name: this.menuPrefix + '[monitor] Show progress bar', + name: this.menuPrefix + ' Progress bar', type: 'boolean', defaultValue: this.defaultShowStatus, onChange: this.showProgressBar, diff --git a/web/styles.d.ts b/web/styles.d.ts new file mode 100644 index 0000000..4d8a4db --- /dev/null +++ b/web/styles.d.ts @@ -0,0 +1,12 @@ +export declare enum Styles { + 'BARS' = "BARS" +} +export declare enum Colors { + 'CPU' = "#0AA015", + 'RAM' = "#07630D", + 'DISK' = "#730F92", + 'GPU' = "#0C86F4", + 'VRAM' = "#176EC7", + 'TEMP_START' = "#00ff00", + 'TEMP_END' = "#ff0000" +} diff --git a/web/styles.js b/web/styles.js new file mode 100644 index 0000000..20edbe3 --- /dev/null +++ b/web/styles.js @@ -0,0 +1,14 @@ +export var Styles; +(function (Styles) { + Styles["BARS"] = "BARS"; +})(Styles || (Styles = {})); +export var Colors; +(function (Colors) { + Colors["CPU"] = "#0AA015"; + Colors["RAM"] = "#07630D"; + Colors["DISK"] = "#730F92"; + Colors["GPU"] = "#0C86F4"; + Colors["VRAM"] = "#176EC7"; + Colors["TEMP_START"] = "#00ff00"; + Colors["TEMP_END"] = "#ff0000"; +})(Colors || (Colors = {})); diff --git a/web/styles.ts b/web/styles.ts new file mode 100644 index 0000000..fa2fa9b --- /dev/null +++ b/web/styles.ts @@ -0,0 +1,13 @@ +export enum Styles { + 'BARS' = 'BARS' +} + +export enum Colors { + 'CPU' = '#0AA015', + 'RAM' = '#07630D', + 'DISK' = '#730F92', + 'GPU' = '#0C86F4', + 'VRAM' = '#176EC7', + 'TEMP_START' = '#00ff00', + 'TEMP_END' = '#ff0000', +} diff --git a/web/types.d.ts b/web/types.d.ts index 2118c88..e1eee71 100644 --- a/web/types.d.ts +++ b/web/types.d.ts @@ -43,6 +43,7 @@ type TStatsSettings = { type TMonitorSettings = { id: string, name: string, + category: string[], // for settings location label: string, // on monitor symbol: string, // on monitor title?: string, // on monitor diff --git a/web/utils.d.ts b/web/utils.d.ts new file mode 100644 index 0000000..14fa9d2 --- /dev/null +++ b/web/utils.d.ts @@ -0,0 +1,3 @@ +export declare function numberToWords(num: number): string; +export declare function toPascalCase(strings: string[]): string; +export declare function convertNumberToPascalCase(num: number): string; diff --git a/web/utils.js b/web/utils.js new file mode 100644 index 0000000..235d0ce --- /dev/null +++ b/web/utils.js @@ -0,0 +1,40 @@ +export function numberToWords(num) { + if (num === 0) + return 'zero'; + const belowTwenty = [ + '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', + 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' + ]; + const tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']; + const thousands = ['', 'thousand', 'million', 'billion']; + function helper(n) { + if (n === 0) + return ''; + else if (n < 20) + return belowTwenty[n] + ' '; + else if (n < 100) + return tens[Math.floor(n / 10)] + ' ' + helper(n % 10); + return belowTwenty[Math.floor(n / 100)] + ' hundred ' + helper(n % 100); + } + let word = ''; + let i = 0; + while (num > 0) { + if (num % 1000 !== 0) { + word = helper(num % 1000) + thousands[i] + ' ' + word; + } + num = Math.floor(num / 1000); + i++; + } + return word.trim(); +} +export function toPascalCase(strings) { + if (!Array.isArray(strings)) + return ''; + function capitalize(word) { + return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); + } + return strings.map(capitalize).join(''); +} +export function convertNumberToPascalCase(num) { + return toPascalCase(numberToWords(num).split(' ')); +} diff --git a/web/utils.ts b/web/utils.ts new file mode 100644 index 0000000..030b47d --- /dev/null +++ b/web/utils.ts @@ -0,0 +1,45 @@ +export function numberToWords(num: number): string { + if (num === 0) return 'zero'; + + const belowTwenty = [ + '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', + 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' + ]; + const tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']; + const thousands = ['', 'thousand', 'million', 'billion']; + + function helper(n: number): string { + if (n === 0) return ''; + else if (n < 20) return belowTwenty[n] + ' '; + else if (n < 100) return tens[Math.floor(n / 10)] + ' ' + helper(n % 10); + return belowTwenty[Math.floor(n / 100)] + ' hundred ' + helper(n % 100); + } + + let word = ''; + let i = 0; + + while (num > 0) { + if (num % 1000 !== 0) { + word = helper(num % 1000) + thousands[i] + ' ' + word; + } + num = Math.floor(num / 1000); + i++; + } + + return word.trim(); +} + +export function toPascalCase(strings: string[]): string { + if (!Array.isArray(strings)) return ''; + + function capitalize(word: string): string { + return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); + } + + return strings.map(capitalize).join(''); +} + + +export function convertNumberToPascalCase(num: number): string { + return toPascalCase(numberToWords(num).split(' ')); +} From 8c5065436261e5ba56b6f76fad1dff3f779574b8 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 15:09:59 +0200 Subject: [PATCH 11/31] menu aligned with save --- web/monitor.js | 31 ++++++++++++++++--------------- web/monitor.ts | 31 ++++++++++++++++--------------- web/progressBar.js | 3 ++- web/progressBar.ts | 3 ++- 4 files changed, 36 insertions(+), 32 deletions(-) diff --git a/web/monitor.js b/web/monitor.js index f714ba6..9fd56cc 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -47,7 +47,8 @@ class CrystoolsMonitor { writable: true, value: { id: 'Crystools.RefreshRate', - name: this.menuPrefix + 'Refresh per second', + name: 'Refresh per second', + category: ['Crystools', this.menuPrefix + ' Refresh Rate'], tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', type: 'slider', attrs: { @@ -108,8 +109,8 @@ class CrystoolsMonitor { writable: true, value: { id: 'Crystools.ShowCpu', - name: this.menuPrefix + ' CPU Usage', - category: ['Crystools', 'Hardware', 'Cpu'], + name: 'CPU Usage', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], type: 'boolean', label: 'CPU', symbol: '%', @@ -132,8 +133,8 @@ class CrystoolsMonitor { writable: true, value: { id: 'Crystools.ShowRam', - name: this.menuPrefix + ' RAM Used', - category: ['Crystools', 'Hardware', 'Ram'], + name: 'RAM Used', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], type: 'boolean', label: 'RAM', symbol: '%', @@ -156,8 +157,8 @@ class CrystoolsMonitor { writable: true, value: { id: 'Crystools.ShowHdd', - name: this.menuPrefix + ' Show HDD Used', - category: ['Crystools', 'Show Hard Disk', 'Show'], + name: 'Show HDD Used', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], type: 'boolean', label: 'HDD', symbol: '%', @@ -180,8 +181,8 @@ class CrystoolsMonitor { writable: true, value: { id: 'Crystools.WhichHdd', - name: this.menuPrefix + ' Partition to show', - category: ['Crystools', 'Show Hard Disk', 'Which'], + name: 'Partition to show', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], type: 'combo', defaultValue: '/', data: [], @@ -233,8 +234,8 @@ class CrystoolsMonitor { } const monitorGPUNElement = { id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), - category: ['Crystools', `Show GPU [${index}] ${name}`, 'Usage'], - name: this.menuPrefix + ' Usage', + name: ' Usage', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], type: 'boolean', label, symbol: '%', @@ -253,8 +254,8 @@ class CrystoolsMonitor { }; const monitorVRAMNElement = { id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), - category: ['Crystools', `Show GPU [${index}] ${name}`, 'VRAM'], - name: this.menuPrefix + ' VRAM', + name: 'VRAM', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], type: 'boolean', label: labelVRAM, symbol: '%', @@ -273,8 +274,8 @@ class CrystoolsMonitor { }; const monitorTemperatureNElement = { id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), - category: ['Crystools', `Show GPU [${index}] ${name}`, 'Temperature'], - name: this.menuPrefix + ' Temperature', + name: 'Temperature', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], type: 'boolean', label: labelTemperature, symbol: '°', diff --git a/web/monitor.ts b/web/monitor.ts index 6e23dd3..ff977b1 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -16,7 +16,8 @@ class CrystoolsMonitor { settingsRate = { id: 'Crystools.RefreshRate', - name: this.menuPrefix + 'Refresh per second', + name: 'Refresh per second', + category: ['Crystools', this.menuPrefix + ' Refresh Rate'], tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', type: 'slider', attrs: { @@ -77,8 +78,8 @@ class CrystoolsMonitor { // CPU Variables monitorCPUElement: TMonitorSettings = { id: 'Crystools.ShowCpu', - name: this.menuPrefix + ' CPU Usage', - category: ['Crystools', 'Hardware', 'Cpu' ], + name: 'CPU Usage', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu' ], type: 'boolean', label: 'CPU', symbol: '%', @@ -98,8 +99,8 @@ class CrystoolsMonitor { // RAM Variables monitorRAMElement: TMonitorSettings = { id: 'Crystools.ShowRam', - name: this.menuPrefix + ' RAM Used', - category: ['Crystools', 'Hardware', 'Ram' ], + name: 'RAM Used', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram' ], type: 'boolean', label: 'RAM', symbol: '%', @@ -119,8 +120,8 @@ class CrystoolsMonitor { // HDD Variables monitorHDDElement: TMonitorSettings = { id: 'Crystools.ShowHdd', - name: this.menuPrefix + ' Show HDD Used', - category: ['Crystools', 'Show Hard Disk', 'Show' ], + name: 'Show HDD Used', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show' ], type: 'boolean', label: 'HDD', symbol: '%', @@ -140,8 +141,8 @@ class CrystoolsMonitor { settingsHDD = { id: 'Crystools.WhichHdd', - name: this.menuPrefix + ' Partition to show', - category: ['Crystools', 'Show Hard Disk', 'Which' ], + name: 'Partition to show', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which' ], type: 'combo', defaultValue: '/', data: [], @@ -204,8 +205,8 @@ class CrystoolsMonitor { // GPU Utilization Variables const monitorGPUNElement: TMonitorSettings = { id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), - category: ['Crystools', `Show GPU [${index}] ${name}`, 'Usage' ], - name: this.menuPrefix + ' Usage', + name: ' Usage', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage' ], type: 'boolean', label, symbol: '%', @@ -226,8 +227,8 @@ class CrystoolsMonitor { // GPU VRAM Variables const monitorVRAMNElement: TMonitorSettings = { id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), - category: ['Crystools', `Show GPU [${index}] ${name}`, 'VRAM' ], - name: this.menuPrefix + ' VRAM', + name: 'VRAM', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM' ], type: 'boolean', label: labelVRAM, symbol: '%', @@ -248,8 +249,8 @@ class CrystoolsMonitor { // GPU Temperature Variables const monitorTemperatureNElement: TMonitorSettings = { id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), - category: ['Crystools', `Show GPU [${index}] ${name}`, 'Temperature' ], - name: this.menuPrefix + ' Temperature', + name: 'Temperature', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature' ], type: 'boolean', label: labelTemperature, symbol: '°', diff --git a/web/progressBar.js b/web/progressBar.js index 59e1737..a059daa 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -88,7 +88,8 @@ class CrystoolsProgressBar { value: () => { app.ui.settings.addSetting({ id: this.idShowProgressBar, - name: this.menuPrefix + ' Progress bar', + name: 'Show progress bar', + category: ['Crystools', this.menuPrefix + ' Progress Bar', 'Show'], type: 'boolean', defaultValue: this.defaultShowStatus, onChange: this.showProgressBar, diff --git a/web/progressBar.ts b/web/progressBar.ts index 0951a96..4d26634 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -28,7 +28,8 @@ class CrystoolsProgressBar { createSettings = (): void => { app.ui.settings.addSetting({ id: this.idShowProgressBar, - name: this.menuPrefix + ' Progress bar', + name: 'Show progress bar', + category: ['Crystools', this.menuPrefix + ' Progress Bar', 'Show' ], type: 'boolean', defaultValue: this.defaultShowStatus, onChange: this.showProgressBar, From ae0d60a45a1a6ea93499425cde5d26c8cb30efb1 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 20:19:49 +0200 Subject: [PATCH 12/31] abstract implemented --- .eslintrc.cjs | 4 +- __init__.py | 2 +- core/version.py | 2 +- pyproject.toml | 2 +- version | 2 +- web/common.js | 4 +- web/common.ts | 4 +- web/debugger.js | 16 ++----- web/debugger.ts | 18 +++----- web/monitor.css | 72 +++++++++++++++++++++++++++++++ web/monitor.js | 32 ++++---------- web/monitor.ts | 64 ++++++++++------------------ web/monitorUI.d.ts | 21 +++++---- web/monitorUI.js | 76 ++++++++------------------------- web/monitorUI.ts | 90 ++++++++++++--------------------------- web/progressBar.js | 20 +++------ web/progressBar.ts | 28 +++--------- web/progressBarUI.d.ts | 19 ++++++--- web/progressBarUI.js | 90 ++++++++++++++++++--------------------- web/progressBarUI.ts | 96 +++++++++++++++++++++--------------------- web/styles.js | 3 ++ web/styles.ts | 6 +++ web/utils.d.ts | 1 + web/utils.js | 17 ++++++++ web/utils.ts | 21 +++++++++ 25 files changed, 338 insertions(+), 372 deletions(-) create mode 100644 web/monitor.css diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 45660ae..2659208 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -58,8 +58,8 @@ module.exports = { // false positive https://github.com/typescript-eslint/typescript-eslint/issues/2483 'no-shadow': 'off', 'object-curly-newline': ["error", { - "ObjectExpression": { "multiline": true, "minProperties": 1 }, - "ObjectPattern": { "multiline": true, "minProperties": 1 }, + "ObjectExpression": { "multiline": true, "minProperties": 8 }, + "ObjectPattern": { "multiline": true, "minProperties": 8 }, "ImportDeclaration": {"multiline": true, "minProperties": 8 }, "ExportDeclaration": { "multiline": true, "minProperties": 8 } }], diff --git a/__init__.py b/__init__.py index 2ea2d8e..326a62a 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ @author: Crystian @title: Crystools @nickname: Crystools -@version: 1.16.6 +@version: 1.17.0 @project: "https://github.com/crystian/ComfyUI-Crystools", @description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia """ diff --git a/core/version.py b/core/version.py index 3e213d1..89a555d 100644 --- a/core/version.py +++ b/core/version.py @@ -1 +1 @@ -version = "1.16.6" +version = "1.17.0" diff --git a/pyproject.toml b/pyproject.toml index eab91a3..73be846 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-crystools" description = "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." -version = "1.16.6" +version = "1.17.0" license = { file = "LICENSE" } dependencies = ["deepdiff", "torch", "numpy", "Pillow", "pynvml", "py-cpuinfo"] diff --git a/version b/version index de646d2..092afa1 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.16.6 +1.17.0 diff --git a/web/common.js b/web/common.js index a54e998..7700b64 100644 --- a/web/common.js +++ b/web/common.js @@ -14,9 +14,7 @@ export function displayContext(nodeType, appFromArg, index = 0, serialize_widget this.serialize_widgets = serialize_widgets; this.isVirtualNode = isVirtualNode; const widget = ComfyWidgets.STRING(this, 'text', [ - 'STRING', { - multiline: true, - }, + 'STRING', { multiline: true }, ], appFromArg).widget; widget.inputEl.readOnly = true; widget.inputEl.style.opacity = 0.6; diff --git a/web/common.ts b/web/common.ts index 09bd981..b19cb72 100644 --- a/web/common.ts +++ b/web/common.ts @@ -25,9 +25,7 @@ export function displayContext( this.isVirtualNode = isVirtualNode; const widget = ComfyWidgets.STRING(this, 'text', [ - 'STRING', { - multiline: true, - }, + 'STRING', { multiline: true }, ], appFromArg).widget; widget.inputEl.readOnly = true; widget.inputEl.style.opacity = 0.6; diff --git a/web/debugger.js b/web/debugger.js index ecc060f..395edd2 100644 --- a/web/debugger.js +++ b/web/debugger.js @@ -54,25 +54,17 @@ app.registerExtension({ this.serialize_widgets = false; this.isVirtualNode = true; const widget = ComfyWidgets.STRING(this, '', [ - '', { - default: '', multiline: true, - }, + '', { default: '', multiline: true }, ], app).widget; widget.inputEl.readOnly = true; ComfyWidgets.BOOLEAN(this, 'Active', [ - '', { - default: true, - }, + '', { default: true }, ]); ComfyWidgets.BOOLEAN(this, 'Parsed', [ - '', { - default: true, - }, + '', { default: true }, ]); ComfyWidgets.COMBO(this, 'What', [ - ['Prompt', 'Workflow'], { - default: 'Prompt', - }, + ['Prompt', 'Workflow'], { default: 'Prompt' }, ]); api.addEventListener('executed', this.fillMetadataWidget, false); } diff --git a/web/debugger.ts b/web/debugger.ts index 26faa54..b37f8a2 100644 --- a/web/debugger.ts +++ b/web/debugger.ts @@ -23,25 +23,17 @@ app.registerExtension({ this.isVirtualNode = true; const widget = ComfyWidgets.STRING(this, '', [ - '', { - default: '', multiline: true, - }, + '', {default: '', multiline: true}, ], app).widget; widget.inputEl.readOnly = true; ComfyWidgets.BOOLEAN(this, 'Active', [ - '', { - default: true, - }, + '', {default: true}, ]); ComfyWidgets.BOOLEAN(this, 'Parsed', [ - '', { - default: true, - }, + '', {default: true}, ]); ComfyWidgets.COMBO(this, 'What', [ - ['Prompt', 'Workflow'], { - default: 'Prompt', - }, + ['Prompt', 'Workflow'], {default: 'Prompt'}, ]); // It runs at finish on each prompt queue @@ -52,7 +44,7 @@ app.registerExtension({ return app.graphToPrompt() .then((workflow: any): string => { let result = 'inactive'; - if(this.widgets?.length !== 4) { + if (this.widgets?.length !== 4) { console.error('Something is wrong with the widgets, should be 4!'); return 'error'; } diff --git a/web/monitor.css b/web/monitor.css new file mode 100644 index 0000000..1903295 --- /dev/null +++ b/web/monitor.css @@ -0,0 +1,72 @@ +#crystools-root { + /*background-color: red;*/ + display: flex; + width: 100%; + flex-direction: column; + + .crystools-monitor-container { + width: 100%; + cursor: crosshair; + order: 3; + margin: 4px 0; + + .crystools-monitor { + margin: 2px 10px; + height: 12px; + position: relative; + display: flex; + align-items: center; + flex-direction: row; + } + + .crystools-text { + width: 35px; + font-size: 10px; + } + + .crystools-content { + height: 100%; + flex-grow: 1; + position: relative; + background-color: var(--bg-color); + } + + .crystools-slider { + position: absolute; + height: 100%; + width: 0; + } + + .crystools-label { + position: relative; + width: 100%; + color: var(--drag-text); + font-size: 10px; + } + + .crystools-progress-bar { + cursor: pointer; + margin: 0 2px; + height: 18px; + position: relative; + background-color: var(--bg-color); + + .crystools-slider { + position: absolute; + height: 100%; + width: 0; + transition: width 0.2s; + background-color: green; + } + + .crystools-label { + position: absolute; + margin: auto 0; + width: 100%; + color: var(--drag-text); + font-size: 14px; + } + } + } + +} diff --git a/web/monitor.js b/web/monitor.js index 9fd56cc..977d957 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -70,9 +70,7 @@ class CrystoolsMonitor { return; } try { - await this.updateServer({ - rate: valueNumber, - }); + await this.updateServer({ rate: valueNumber }); } catch (error) { console.error(error); @@ -121,9 +119,7 @@ class CrystoolsMonitor { cssColor: Colors.CPU, onChange: async (value) => { this.monitorUI?.updateWidget(this.monitorCPUElement); - await this.updateServer({ - switchCPU: value, - }); + await this.updateServer({ switchCPU: value }); }, } }); @@ -145,9 +141,7 @@ class CrystoolsMonitor { cssColor: Colors.RAM, onChange: async (value) => { this.monitorUI?.updateWidget(this.monitorRAMElement); - await this.updateServer({ - switchRAM: value, - }); + await this.updateServer({ switchRAM: value }); }, } }); @@ -169,9 +163,7 @@ class CrystoolsMonitor { cssColor: Colors.DISK, onChange: async (value) => { this.monitorUI?.updateWidget(this.monitorHDDElement); - await this.updateServer({ - switchHDD: value, - }); + await this.updateServer({ switchHDD: value }); }, } }); @@ -195,9 +187,7 @@ class CrystoolsMonitor { })); }, onChange: async (value) => { - await this.updateServer({ - whichHDD: value, - }); + await this.updateServer({ whichHDD: value }); }, } }); @@ -247,9 +237,7 @@ class CrystoolsMonitor { cssColor: Colors.GPU, onChange: async (value) => { this.monitorUI?.updateWidget(monitorGPUNElement); - void await this.updateServerGPU(index, { - utilization: value - }); + void await this.updateServerGPU(index, { utilization: value }); }, }; const monitorVRAMNElement = { @@ -267,9 +255,7 @@ class CrystoolsMonitor { cssColor: Colors.VRAM, onChange: async (value) => { this.monitorUI?.updateWidget(monitorVRAMNElement); - void await this.updateServerGPU(index, { - vram: value - }); + void await this.updateServerGPU(index, { vram: value }); }, }; const monitorTemperatureNElement = { @@ -288,9 +274,7 @@ class CrystoolsMonitor { cssColorFinal: Colors.TEMP_END, onChange: async (value) => { this.monitorUI?.updateWidget(monitorTemperatureNElement); - void await this.updateServerGPU(index, { - temperature: value - }); + void await this.updateServerGPU(index, { temperature: value }); }, }; this.monitorGPUSettings[index] = monitorGPUNElement; diff --git a/web/monitor.ts b/web/monitor.ts index ff977b1..7e66ae9 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -39,9 +39,7 @@ class CrystoolsMonitor { return; } try { - await this.updateServer({ - rate: valueNumber, - }); + await this.updateServer({rate: valueNumber}); } catch (error) { console.error(error); return; @@ -79,7 +77,7 @@ class CrystoolsMonitor { monitorCPUElement: TMonitorSettings = { id: 'Crystools.ShowCpu', name: 'CPU Usage', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu' ], + category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], type: 'boolean', label: 'CPU', symbol: '%', @@ -90,9 +88,7 @@ class CrystoolsMonitor { cssColor: Colors.CPU, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(this.monitorCPUElement); - await this.updateServer({ - switchCPU: value, - }); + await this.updateServer({switchCPU: value}); }, }; @@ -100,7 +96,7 @@ class CrystoolsMonitor { monitorRAMElement: TMonitorSettings = { id: 'Crystools.ShowRam', name: 'RAM Used', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram' ], + category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], type: 'boolean', label: 'RAM', symbol: '%', @@ -111,9 +107,7 @@ class CrystoolsMonitor { cssColor: Colors.RAM, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(this.monitorRAMElement); - await this.updateServer({ - switchRAM: value, - }); + await this.updateServer({switchRAM: value}); }, }; @@ -121,7 +115,7 @@ class CrystoolsMonitor { monitorHDDElement: TMonitorSettings = { id: 'Crystools.ShowHdd', name: 'Show HDD Used', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show' ], + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], type: 'boolean', label: 'HDD', symbol: '%', @@ -133,16 +127,14 @@ class CrystoolsMonitor { cssColor: Colors.DISK, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(this.monitorHDDElement); - await this.updateServer({ - switchHDD: value, - }); + await this.updateServer({switchHDD: value}); }, }; settingsHDD = { id: 'Crystools.WhichHdd', name: 'Partition to show', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which' ], + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], type: 'combo', defaultValue: '/', data: [], @@ -156,9 +148,7 @@ class CrystoolsMonitor { })); }, onChange: async(value: string): Promise => { - await this.updateServer({ - whichHDD: value, - }); + await this.updateServer({whichHDD: value}); }, }; @@ -184,11 +174,9 @@ class CrystoolsMonitor { moreThanOneGPU = true; } - gpus?.forEach(({ - name, index - }) => { + gpus?.forEach(({name, index}) => { - if(name === undefined || index === undefined) { + if (name === undefined || index === undefined) { console.warn('getGPUsFromServer: name or index undefined', name, index); return; } @@ -197,16 +185,16 @@ class CrystoolsMonitor { let labelVRAM = 'VRAM'; let labelTemperature = 'Temp'; if (moreThanOneGPU) { - label = 'GPU '+index; - labelVRAM = 'VRAM'+index; - labelTemperature = 'Temp '+index; + label = 'GPU ' + index; + labelVRAM = 'VRAM' + index; + labelTemperature = 'Temp ' + index; } // GPU Utilization Variables const monitorGPUNElement: TMonitorSettings = { id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), name: ' Usage', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage' ], + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], type: 'boolean', label, symbol: '%', @@ -218,9 +206,7 @@ class CrystoolsMonitor { cssColor: Colors.GPU, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(monitorGPUNElement); - void await this.updateServerGPU(index,{ - utilization: value - }); + void await this.updateServerGPU(index, {utilization: value}); }, }; @@ -228,7 +214,7 @@ class CrystoolsMonitor { const monitorVRAMNElement: TMonitorSettings = { id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), name: 'VRAM', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM' ], + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], type: 'boolean', label: labelVRAM, symbol: '%', @@ -240,9 +226,7 @@ class CrystoolsMonitor { cssColor: Colors.VRAM, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(monitorVRAMNElement); - void await this.updateServerGPU(index,{ - vram: value - }); + void await this.updateServerGPU(index, {vram: value}); }, }; @@ -250,7 +234,7 @@ class CrystoolsMonitor { const monitorTemperatureNElement: TMonitorSettings = { id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), name: 'Temperature', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature' ], + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], type: 'boolean', label: labelTemperature, symbol: '°', @@ -263,9 +247,7 @@ class CrystoolsMonitor { cssColorFinal: Colors.TEMP_END, onChange: async(value: boolean) => { this.monitorUI?.updateWidget(monitorTemperatureNElement); - void await this.updateServerGPU(index,{ - temperature: value - }); + void await this.updateServerGPU(index, {temperature: value}); }, }; @@ -314,7 +296,7 @@ class CrystoolsMonitor { return this.getDataFromServer('GPU'); }; - getDataFromServer = async(what: string): Promise => { + getDataFromServer = async (what: string): Promise => { const resp = await api.fetchApi(`/crystools/monitor/${what}`, { method: 'GET', cache: 'no-store', @@ -336,8 +318,8 @@ class CrystoolsMonitor { this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, - currentRate - ); + currentRate, + ); this.registerListeners(); } diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts index 696666e..124ae33 100644 --- a/web/monitorUI.d.ts +++ b/web/monitorUI.d.ts @@ -1,16 +1,15 @@ -export declare class MonitorUI { - monitorCPUElement: TMonitorSettings; - monitorRAMElement: TMonitorSettings; - monitorHDDElement: TMonitorSettings; - monitorGPUSettings: TMonitorSettings[]; - monitorVRAMSettings: TMonitorSettings[]; - monitorTemperatureSettings: TMonitorSettings[]; - currentRate: number; - htmlIdCrystoolsRoot: string; - htmlIdCrystoolsMonitorContainer: string; +import { ProgressBarUIBase } from './progressBarUI.js'; +export declare class MonitorUI extends ProgressBarUIBase { + private monitorCPUElement; + private monitorRAMElement; + private monitorHDDElement; + private monitorGPUSettings; + private monitorVRAMSettings; + private monitorTemperatureSettings; + private currentRate; constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number); refreshDisplay: () => void; - createVertical: () => void; + createDOM: () => void; updateAllWidget: () => void; updateWidget: (monitorSettings: TMonitorSettings) => void; updateAllMonitors: (data: TStatsData) => void; diff --git a/web/monitorUI.js b/web/monitorUI.js index 51f8148..369eb30 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,6 +1,8 @@ import { app } from './comfy/index.js'; -export class MonitorUI { +import { ProgressBarUIBase } from './progressBarUI.js'; +export class MonitorUI extends ProgressBarUIBase { constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { + super(); Object.defineProperty(this, "monitorCPUElement", { enumerable: true, configurable: true, @@ -43,18 +45,6 @@ export class MonitorUI { writable: true, value: currentRate }); - Object.defineProperty(this, "htmlIdCrystoolsRoot", { - enumerable: true, - configurable: true, - writable: true, - value: 'crystools-root' - }); - Object.defineProperty(this, "htmlIdCrystoolsMonitorContainer", { - enumerable: true, - configurable: true, - writable: true, - value: 'crystools-monitor-container' - }); Object.defineProperty(this, "refreshDisplay", { enumerable: true, configurable: true, @@ -64,37 +54,20 @@ export class MonitorUI { this.updateAllWidget(); } }); - Object.defineProperty(this, "createVertical", { + Object.defineProperty(this, "createDOM", { enumerable: true, configurable: true, writable: true, value: () => { - const parentElement = document.getElementById('queue-button'); - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); - } - const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsMonitorContainer); - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'crosshair'; - htmlContainer.style.order = '3'; - htmlContainer.style.margin = '4px 0'; - ctoolsRoot.append(htmlContainer); - htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); + this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); + this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); this.monitorTemperatureSettings[index] && - htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); + this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); }); - htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); this.updateAllAnimationDuration(this.currentRate); this.updateAllWidget(); } @@ -233,31 +206,20 @@ export class MonitorUI { } const htmlMain = document.createElement('div'); htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.style.margin = '2px 10px'; - htmlMain.style.height = '12px'; - htmlMain.style.position = 'relative'; - htmlMain.style.display = 'flex'; - htmlMain.style.alignItems = 'center'; - htmlMain.style.flexDirection = 'row'; + htmlMain.classList.add('crystools-monitor'); monitorSettings.htmlMonitorRef = htmlMain; if (monitorSettings.title) { htmlMain.title = monitorSettings.title; } const htmlMonitorText = document.createElement('div'); - htmlMonitorText.style.width = '35px'; - htmlMonitorText.style.fontSize = '10px'; + htmlMonitorText.classList.add('crystools-text'); htmlMonitorText.innerHTML = monitorSettings.label; htmlMain.append(htmlMonitorText); const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.style.height = '100%'; - htmlMonitorContent.style.flexGrow = '1'; - htmlMonitorContent.style.position = 'relative'; - htmlMonitorContent.style.backgroundColor = 'var(--bg-color)'; + htmlMonitorContent.classList.add('crystools-content'); htmlMain.append(htmlMonitorContent); const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.style.position = 'absolute'; - htmlMonitorSlider.style.height = '100%'; - htmlMonitorSlider.style.width = '0'; + htmlMonitorSlider.classList.add('crystools-slider'); if (monitorSettings.cssColorFinal) { htmlMonitorSlider.style.backgroundColor = `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; @@ -268,17 +230,13 @@ export class MonitorUI { monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; htmlMonitorContent.append(htmlMonitorSlider); const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.style.position = 'relative'; - htmlMonitorLabel.style.width = '100%'; - htmlMonitorLabel.style.color = 'var(--drag-text)'; - htmlMonitorLabel.style.fontSize = '10px'; - htmlMonitorLabel.innerHTML = '0%'; + htmlMonitorLabel.classList.add('crystools-label'); monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; htmlMonitorContent.append(htmlMonitorLabel); + htmlMonitorLabel.innerHTML = '0%'; return monitorSettings.htmlMonitorRef; } }); - this.createVertical(); - window.addEventListener('resize', this.refreshDisplay); + this.createDOM(); } } diff --git a/web/monitorUI.ts b/web/monitorUI.ts index 716e93a..0ac0f57 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -1,21 +1,18 @@ import { app } from './comfy/index.js'; +import { ProgressBarUIBase } from './progressBarUI.js'; -export class MonitorUI { - htmlIdCrystoolsRoot = 'crystools-root'; - htmlIdCrystoolsMonitorContainer = 'crystools-monitor-container'; - +export class MonitorUI extends ProgressBarUIBase { constructor( - public monitorCPUElement: TMonitorSettings, - public monitorRAMElement: TMonitorSettings, - public monitorHDDElement: TMonitorSettings, - public monitorGPUSettings: TMonitorSettings[], - public monitorVRAMSettings: TMonitorSettings[], - public monitorTemperatureSettings: TMonitorSettings[], - public currentRate: number + private monitorCPUElement: TMonitorSettings, + private monitorRAMElement: TMonitorSettings, + private monitorHDDElement: TMonitorSettings, + private monitorGPUSettings: TMonitorSettings[], + private monitorVRAMSettings: TMonitorSettings[], + private monitorTemperatureSettings: TMonitorSettings[], + private currentRate: number ) { - this.createVertical(); - - window.addEventListener('resize', this.refreshDisplay); + super(); + this.createDOM(); } refreshDisplay = (): void => { @@ -23,29 +20,9 @@ export class MonitorUI { this.updateAllWidget(); }; - createVertical = (): void => { - const parentElement = document.getElementById('queue-button'); - - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); - } - - const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsMonitorContainer); - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'crosshair'; - htmlContainer.style.order = '3'; - htmlContainer.style.margin = '4px 0'; - ctoolsRoot.append(htmlContainer); - - htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + override createDOM = (): void => { + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); // gpu0 > gpu1 > vram0 > vram1 // this.monitorGPUSettings.forEach((monitorSettings) => { @@ -60,13 +37,13 @@ export class MonitorUI { // gpu0 > vram0 > gpu1 > vram1 this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); + this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); + this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); this.monitorTemperatureSettings[index] && - htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); + this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); }); - htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); this.updateAllAnimationDuration(this.currentRate); this.updateAllWidget(); @@ -89,6 +66,10 @@ export class MonitorUI { }); }; + /** + * for the settings menu + * @param monitorSettings + */ updateWidget = (monitorSettings: TMonitorSettings): void => { const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); if (monitorSettings.htmlMonitorRef) { @@ -195,12 +176,7 @@ export class MonitorUI { } const htmlMain = document.createElement('div'); htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.style.margin = '2px 10px'; - htmlMain.style.height = '12px'; - htmlMain.style.position = 'relative'; - htmlMain.style.display = 'flex'; - htmlMain.style.alignItems = 'center'; - htmlMain.style.flexDirection = 'row'; + htmlMain.classList.add('crystools-monitor'); monitorSettings.htmlMonitorRef = htmlMain; if (monitorSettings.title) { @@ -208,22 +184,16 @@ export class MonitorUI { } const htmlMonitorText = document.createElement('div'); - htmlMonitorText.style.width = '35px'; - htmlMonitorText.style.fontSize = '10px'; + htmlMonitorText.classList.add('crystools-text'); htmlMonitorText.innerHTML = monitorSettings.label; htmlMain.append(htmlMonitorText); const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.style.height = '100%'; - htmlMonitorContent.style.flexGrow = '1'; - htmlMonitorContent.style.position = 'relative'; - htmlMonitorContent.style.backgroundColor = 'var(--bg-color)'; + htmlMonitorContent.classList.add('crystools-content'); htmlMain.append(htmlMonitorContent); const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.style.position = 'absolute'; - htmlMonitorSlider.style.height = '100%'; - htmlMonitorSlider.style.width = '0'; + htmlMonitorSlider.classList.add('crystools-slider'); if(monitorSettings.cssColorFinal){ htmlMonitorSlider.style.backgroundColor = `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; @@ -234,14 +204,10 @@ export class MonitorUI { htmlMonitorContent.append(htmlMonitorSlider); const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.style.position = 'relative'; - htmlMonitorLabel.style.width = '100%'; - htmlMonitorLabel.style.color = 'var(--drag-text)'; - htmlMonitorLabel.style.fontSize = '10px'; - htmlMonitorLabel.innerHTML = '0%'; + htmlMonitorLabel.classList.add('crystools-label'); monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; htmlMonitorContent.append(htmlMonitorLabel); - + htmlMonitorLabel.innerHTML = '0%'; return monitorSettings.htmlMonitorRef; }; } diff --git a/web/progressBar.js b/web/progressBar.js index a059daa..98c8699 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -27,12 +27,6 @@ class CrystoolsProgressBar { writable: true, value: commonPrefix }); - Object.defineProperty(this, "htmlIdCrystoolsRoot", { - enumerable: true, - configurable: true, - writable: true, - value: 'crystools-root' - }); Object.defineProperty(this, "htmlIdCrystoolsProgressBarContainer", { enumerable: true, configurable: true, @@ -120,7 +114,7 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: () => { - api.addEventListener('status', ({ detail, }) => { + api.addEventListener('status', ({ detail }) => { this.currentStatus = this.currentStatus === EStatus.execution_error ? EStatus.execution_error : EStatus.executed; const queueRemaining = detail?.exec_info.queue_remaining; if (queueRemaining) { @@ -128,8 +122,8 @@ class CrystoolsProgressBar { } this.updateDisplay(); }, false); - api.addEventListener('progress', ({ detail, }) => { - const { value, max, node, } = detail; + api.addEventListener('progress', ({ detail }) => { + const { value, max, node } = detail; const progress = Math.floor((value / max) * 100); if (!isNaN(progress) && progress >= 0 && progress <= 100) { this.currentProgress = progress; @@ -137,18 +131,18 @@ class CrystoolsProgressBar { } this.updateDisplay(); }, false); - api.addEventListener('executed', ({ detail, }) => { + api.addEventListener('executed', ({ detail }) => { if (detail?.node) { this.currentNode = detail.node; } this.updateDisplay(); }, false); - api.addEventListener('execution_start', ({ _detail, }) => { + api.addEventListener('execution_start', ({ _detail }) => { this.currentStatus = EStatus.executing; this.timeStart = Date.now(); this.updateDisplay(); }, false); - api.addEventListener('execution_error', ({ _detail, }) => { + api.addEventListener('execution_error', ({ _detail }) => { this.currentStatus = EStatus.execution_error; this.updateDisplay(); }, false); @@ -173,7 +167,7 @@ class CrystoolsProgressBar { this.createSettings(); } setup() { - this.progressBarVertical = new ProgressBarUI(this.htmlIdCrystoolsRoot, this.htmlIdCrystoolsProgressBarContainer, this.centerNode); + this.progressBarVertical = new ProgressBarUI(this.htmlIdCrystoolsProgressBarContainer, this.centerNode); this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); diff --git a/web/progressBar.ts b/web/progressBar.ts index 4d26634..1bf03ae 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -7,7 +7,6 @@ class CrystoolsProgressBar { idShowProgressBar = 'Crystools.ProgressBar'; defaultShowStatus = true; menuPrefix = commonPrefix; - htmlIdCrystoolsRoot = 'crystools-root'; htmlIdCrystoolsProgressBarContainer = 'crystools-progress-bar-container'; currentStatus = EStatus.executed; @@ -24,7 +23,7 @@ class CrystoolsProgressBar { this.createSettings(); } - // not on setup because this affect the order on settings, I prefer to options at first + // not on setup because this affect the order on settings, I prefer to options at first createSettings = (): void => { app.ui.settings.addSetting({ id: this.idShowProgressBar, @@ -51,7 +50,6 @@ class CrystoolsProgressBar { setup(): void { this.progressBarVertical = new ProgressBarUI( - this.htmlIdCrystoolsRoot, this.htmlIdCrystoolsProgressBarContainer, this.centerNode); @@ -63,9 +61,7 @@ class CrystoolsProgressBar { } registerListeners = (): void => { - api.addEventListener('status', ({ - detail, - }: any) => { + api.addEventListener('status', ({ detail }: any) => { this.currentStatus = this.currentStatus === EStatus.execution_error ? EStatus.execution_error : EStatus.executed; const queueRemaining = detail?.exec_info.queue_remaining; @@ -75,12 +71,8 @@ class CrystoolsProgressBar { this.updateDisplay(); }, false); - api.addEventListener('progress', ({ - detail, - }: any) => { - const { - value, max, node, - } = detail; + api.addEventListener('progress', ({ detail }: any) => { + const { value, max, node } = detail; const progress = Math.floor((value / max) * 100); if (!isNaN(progress) && progress >= 0 && progress <= 100) { @@ -91,9 +83,7 @@ class CrystoolsProgressBar { this.updateDisplay(); }, false); - api.addEventListener('executed', ({ - detail, - }: any) => { + api.addEventListener('executed', ({ detail }: any) => { if (detail?.node) { this.currentNode = detail.node; } @@ -101,18 +91,14 @@ class CrystoolsProgressBar { this.updateDisplay(); }, false); - api.addEventListener('execution_start', ({ - _detail, - }: any) => { + api.addEventListener('execution_start', ({ _detail }: any) => { this.currentStatus = EStatus.executing; this.timeStart = Date.now(); this.updateDisplay(); }, false); - api.addEventListener('execution_error', ({ - _detail, - }: any) => { + api.addEventListener('execution_error', ({ _detail }: any) => { this.currentStatus = EStatus.execution_error; this.updateDisplay(); diff --git a/web/progressBarUI.d.ts b/web/progressBarUI.d.ts index 800a9ce..9ec0ed3 100644 --- a/web/progressBarUI.d.ts +++ b/web/progressBarUI.d.ts @@ -3,18 +3,25 @@ export declare enum EStatus { executed = "Executed", execution_error = "Execution error" } -export declare class ProgressBarUI { - htmlIdCrystoolsRoot: string; - htmlIdCrystoolsProgressBarContainer: string; +export declare abstract class ProgressBarUIBase { + protected htmlIdCrystoolsRoot: string; + protected htmlClassCrystoolsMonitorContainer: string; + protected htmlContainer: HTMLDivElement; + protected constructor(); + createRoot(): void; + abstract refreshDisplay(): void; + abstract createDOM(): void; +} +export declare class ProgressBarUI extends ProgressBarUIBase { + private htmlIdCrystoolsProgressBarContainer; private centerNode; htmlProgressSliderRef: HTMLDivElement; htmlProgressLabelRef: HTMLDivElement; - queueButtonElement: HTMLElement | null; currentStatus: EStatus; timeStart: number; currentProgress: number; - constructor(htmlIdCrystoolsRoot: string, htmlIdCrystoolsProgressBarContainer: string, centerNode: () => void); - createVertical: () => void; + constructor(htmlIdCrystoolsProgressBarContainer: string, centerNode: () => void); + createDOM: () => void; refreshDisplay: () => void; updateDisplay: (currentStatus: EStatus, timeStart: number, currentProgress: number) => void; } diff --git a/web/progressBarUI.js b/web/progressBarUI.js index d7f46f2..a5769d2 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,18 +1,48 @@ -import { app } from './comfy/index.js'; export var EStatus; (function (EStatus) { EStatus["executing"] = "Executing"; EStatus["executed"] = "Executed"; EStatus["execution_error"] = "Execution error"; })(EStatus || (EStatus = {})); -export class ProgressBarUI { - constructor(htmlIdCrystoolsRoot, htmlIdCrystoolsProgressBarContainer, centerNode) { +export class ProgressBarUIBase { + constructor() { Object.defineProperty(this, "htmlIdCrystoolsRoot", { enumerable: true, configurable: true, writable: true, - value: htmlIdCrystoolsRoot + value: 'crystools-root' }); + Object.defineProperty(this, "htmlClassCrystoolsMonitorContainer", { + enumerable: true, + configurable: true, + writable: true, + value: 'crystools-monitor-container' + }); + Object.defineProperty(this, "htmlContainer", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + this.createRoot(); + window.addEventListener('resize', () => this.refreshDisplay()); + } + createRoot() { + let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); + if (!ctoolsRoot) { + ctoolsRoot = document.createElement('div'); + ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); + const parentElement = document.getElementById('queue-button'); + parentElement?.insertAdjacentElement('afterend', ctoolsRoot); + } + this.htmlContainer = document.createElement('div'); + this.htmlContainer.classList.add(this.htmlClassCrystoolsMonitorContainer); + ctoolsRoot.append(this.htmlContainer); + } +} +export class ProgressBarUI extends ProgressBarUIBase { + constructor(htmlIdCrystoolsProgressBarContainer, centerNode) { + super(); Object.defineProperty(this, "htmlIdCrystoolsProgressBarContainer", { enumerable: true, configurable: true, @@ -37,12 +67,6 @@ export class ProgressBarUI { writable: true, value: void 0 }); - Object.defineProperty(this, "queueButtonElement", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); Object.defineProperty(this, "currentStatus", { enumerable: true, configurable: true, @@ -61,49 +85,26 @@ export class ProgressBarUI { writable: true, value: void 0 }); - Object.defineProperty(this, "createVertical", { + Object.defineProperty(this, "createDOM", { enumerable: true, configurable: true, writable: true, value: () => { - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - this.queueButtonElement?.insertAdjacentElement('afterend', ctoolsRoot); - } const htmlContainer = document.createElement('div'); htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); - htmlContainer.style.margin = '4px 0'; - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'pointer'; - htmlContainer.style.order = '1'; htmlContainer.addEventListener('click', this.centerNode); - ctoolsRoot.append(htmlContainer); + this.htmlContainer.append(htmlContainer); + this.htmlContainer.style.order = '1'; const progressBar = document.createElement('div'); - progressBar.style.margin = '0 10px'; - progressBar.style.height = '18px'; - progressBar.style.position = 'relative'; - progressBar.style.backgroundColor = 'var(--bg-color)'; + progressBar.classList.add('crystools-progress-bar'); htmlContainer.append(progressBar); const progressSlider = document.createElement('div'); - progressSlider.style.position = 'absolute'; - progressSlider.style.height = '100%'; - progressSlider.style.width = '0'; - progressSlider.style.transition = 'width 0.2s'; - progressSlider.style.backgroundColor = 'green'; this.htmlProgressSliderRef = progressSlider; + progressSlider.classList.add('crystools-slider'); progressBar.append(this.htmlProgressSliderRef); const progressLabel = document.createElement('div'); - progressLabel.style.position = 'absolute'; - progressLabel.style.margin = 'auto 0'; - progressLabel.style.width = '100%'; - progressLabel.style.color = 'var(--drag-text)'; - progressLabel.style.fontSize = '14px'; + progressLabel.classList.add('crystools-label'); progressLabel.innerHTML = '0%'; this.htmlProgressLabelRef = progressLabel; progressBar.append(this.htmlProgressLabelRef); @@ -129,8 +130,6 @@ export class ProgressBarUI { this.currentStatus = currentStatus; this.timeStart = timeStart; this.currentProgress = currentProgress; - const menu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - console.log('menu', menu); if (currentStatus === EStatus.executed) { this.htmlProgressLabelRef.innerHTML = 'cached'; const timeElapsed = Date.now() - timeStart; @@ -150,13 +149,6 @@ export class ProgressBarUI { } } }); - this.htmlIdCrystoolsRoot = htmlIdCrystoolsRoot; - this.htmlIdCrystoolsProgressBarContainer = htmlIdCrystoolsProgressBarContainer; - this.queueButtonElement = document.getElementById('queue-button'); - if (!this.queueButtonElement) { - throw new Error('queue-button not found'); - } - this.createVertical(); - window.addEventListener('resize', this.refreshDisplay); + this.createDOM(); } } diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index 04cf81f..f826eac 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -1,4 +1,4 @@ -import { app } from './comfy/index.js'; +// import { app } from './comfy/index.js'; export enum EStatus { executing = 'Executing', @@ -6,74 +6,71 @@ export enum EStatus { execution_error = 'Execution error', } -export class ProgressBarUI { - htmlProgressSliderRef: HTMLDivElement; - htmlProgressLabelRef: HTMLDivElement; - queueButtonElement: HTMLElement | null; - currentStatus: EStatus; - timeStart: number; - currentProgress: number; +export abstract class ProgressBarUIBase { + protected htmlIdCrystoolsRoot = 'crystools-root'; + protected htmlClassCrystoolsMonitorContainer = 'crystools-monitor-container'; + protected htmlContainer: HTMLDivElement; - constructor( - public htmlIdCrystoolsRoot: string, - public htmlIdCrystoolsProgressBarContainer: string, - private centerNode: () => void - ) { - this.htmlIdCrystoolsRoot = htmlIdCrystoolsRoot; - this.htmlIdCrystoolsProgressBarContainer = htmlIdCrystoolsProgressBarContainer; - this.queueButtonElement = document.getElementById('queue-button'); - if (!this.queueButtonElement) { - throw new Error('queue-button not found'); - } - - this.createVertical(); - - window.addEventListener('resize', this.refreshDisplay); + protected constructor() { + this.createRoot(); + window.addEventListener('resize', () => this.refreshDisplay()); } - createVertical = (): void => { + createRoot(): void { + // IMPORTANT duplicate by progressbar and crystools-save let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); if (!ctoolsRoot) { ctoolsRoot = document.createElement('div'); ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - ctoolsRoot.style.display = 'flex'; - ctoolsRoot.style.width = '100%'; - ctoolsRoot.style.flexDirection = 'column'; - this.queueButtonElement?.insertAdjacentElement('afterend', ctoolsRoot); + + // the best parentElement: + const parentElement = document.getElementById('queue-button'); + parentElement?.insertAdjacentElement('afterend', ctoolsRoot); } + this.htmlContainer = document.createElement('div'); + this.htmlContainer.classList.add(this.htmlClassCrystoolsMonitorContainer); + ctoolsRoot.append(this.htmlContainer); + } + + abstract refreshDisplay(): void; + abstract createDOM(): void; +} + +export class ProgressBarUI extends ProgressBarUIBase{ + htmlProgressSliderRef: HTMLDivElement; + htmlProgressLabelRef: HTMLDivElement; + currentStatus: EStatus; + timeStart: number; + currentProgress: number; + + constructor ( + private htmlIdCrystoolsProgressBarContainer: string, + private centerNode: () => void + ) { + super(); + this.createDOM(); + } + + createDOM = (): void => { const htmlContainer = document.createElement('div'); htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); - htmlContainer.style.margin = '4px 0'; - htmlContainer.style.width = '100%'; - htmlContainer.style.cursor = 'pointer'; - htmlContainer.style.order = '1'; htmlContainer.addEventListener('click', this.centerNode); - ctoolsRoot.append(htmlContainer); + this.htmlContainer.append(htmlContainer); + this.htmlContainer.style.order = '1'; const progressBar = document.createElement('div'); - progressBar.style.margin = '0 10px'; - progressBar.style.height = '18px'; - progressBar.style.position = 'relative'; - progressBar.style.backgroundColor = 'var(--bg-color)'; + progressBar.classList.add('crystools-progress-bar'); htmlContainer.append(progressBar); const progressSlider = document.createElement('div'); - progressSlider.style.position = 'absolute'; - progressSlider.style.height = '100%'; - progressSlider.style.width = '0'; - progressSlider.style.transition = 'width 0.2s'; - progressSlider.style.backgroundColor = 'green'; this.htmlProgressSliderRef = progressSlider; + progressSlider.classList.add('crystools-slider'); progressBar.append(this.htmlProgressSliderRef); const progressLabel = document.createElement('div'); - progressLabel.style.position = 'absolute'; - progressLabel.style.margin = 'auto 0'; - progressLabel.style.width = '100%'; - progressLabel.style.color = 'var(--drag-text)'; - progressLabel.style.fontSize = '14px'; + progressLabel.classList.add('crystools-label'); progressLabel.innerHTML = '0%'; this.htmlProgressLabelRef = progressLabel; progressBar.append(this.htmlProgressLabelRef); @@ -93,8 +90,9 @@ export class ProgressBarUI { this.timeStart = timeStart; this.currentProgress = currentProgress; - const menu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - console.log('menu', menu); + // TODO from here! + // const menu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + // console.log('menu', menu); if (currentStatus === EStatus.executed) { // finished diff --git a/web/styles.js b/web/styles.js index 20edbe3..a36838e 100644 --- a/web/styles.js +++ b/web/styles.js @@ -1,3 +1,6 @@ +import { injectCss } from './utils.js'; +void injectCss('extensions/ComfyUI-Crystools/monitor.css').then(() => { +}); export var Styles; (function (Styles) { Styles["BARS"] = "BARS"; diff --git a/web/styles.ts b/web/styles.ts index fa2fa9b..4db23f9 100644 --- a/web/styles.ts +++ b/web/styles.ts @@ -1,3 +1,9 @@ +import { injectCss } from './utils.js'; + +void injectCss('extensions/ComfyUI-Crystools/monitor.css').then(() => { + // console.log('injectCss'); +}); + export enum Styles { 'BARS' = 'BARS' } diff --git a/web/utils.d.ts b/web/utils.d.ts index 14fa9d2..01e61fc 100644 --- a/web/utils.d.ts +++ b/web/utils.d.ts @@ -1,3 +1,4 @@ export declare function numberToWords(num: number): string; export declare function toPascalCase(strings: string[]): string; export declare function convertNumberToPascalCase(num: number): string; +export declare function injectCss(href: string): Promise; diff --git a/web/utils.js b/web/utils.js index 235d0ce..e9e0a38 100644 --- a/web/utils.js +++ b/web/utils.js @@ -38,3 +38,20 @@ export function toPascalCase(strings) { export function convertNumberToPascalCase(num) { return toPascalCase(numberToWords(num).split(' ')); } +export function injectCss(href) { + if (document.querySelector(`link[href^='${href}']`)) { + return Promise.resolve(); + } + return new Promise((resolve) => { + const link = document.createElement('link'); + link.setAttribute('rel', 'stylesheet'); + link.setAttribute('type', 'text/css'); + const timeout = setTimeout(resolve, 1000); + link.addEventListener('load', (_e) => { + clearInterval(timeout); + resolve(); + }); + link.href = href; + document.head.appendChild(link); + }); +} diff --git a/web/utils.ts b/web/utils.ts index 030b47d..b407610 100644 --- a/web/utils.ts +++ b/web/utils.ts @@ -43,3 +43,24 @@ export function toPascalCase(strings: string[]): string { export function convertNumberToPascalCase(num: number): string { return toPascalCase(numberToWords(num).split(' ')); } + +/** + * Injects CSS into the page with a promise when complete. + */ +export function injectCss(href: string): Promise { + if (document.querySelector(`link[href^='${href}']`)) { + return Promise.resolve(); + } + return new Promise((resolve) => { + const link = document.createElement('link'); + link.setAttribute('rel', 'stylesheet'); + link.setAttribute('type', 'text/css'); + const timeout = setTimeout(resolve, 1000); + link.addEventListener('load', (_e) => { + clearInterval(timeout); + resolve(); + }); + link.href = href; + document.head.appendChild(link); + }); +} From 65810e707bede6f1a84d241fbf193511e0a0f73c Mon Sep 17 00:00:00 2001 From: Crystian Date: Sat, 21 Sep 2024 23:13:58 +0200 Subject: [PATCH 13/31] starting with horizontal... finally --- README.md | 5 + web/monitor.d.ts | 1 - web/monitor.js | 379 +---------------------- web/monitor.ts | 682 ++++++++++++++++++++--------------------- web/monitorUI.d.ts | 20 -- web/monitorUI.js | 243 +-------------- web/monitorUI.ts | 426 ++++++++++++------------- web/progressBar.js | 44 ++- web/progressBar.ts | 63 +++- web/progressBarUI.d.ts | 7 +- web/progressBarUI.js | 34 +- web/progressBarUI.ts | 35 ++- 12 files changed, 711 insertions(+), 1228 deletions(-) diff --git a/README.md b/README.md index c57a501..00c59e1 100644 --- a/README.md +++ b/README.md @@ -512,6 +512,11 @@ You have predefined switches (string, latent, image, conditioning) but you can u ### Crystools +### 1.17.0 (21/09/2024) +- Settings menu reorganized +- Preparing for horizontal UI +- Update from ComfyUI (typescript and new features) + ### 1.16.0 (31/07/2024) - Rollback of AMD support by manager does not support other repository parameter (https://test.pypi.org/simple by pyrsmi) diff --git a/web/monitor.d.ts b/web/monitor.d.ts index cb0ff5c..e69de29 100644 --- a/web/monitor.d.ts +++ b/web/monitor.d.ts @@ -1 +0,0 @@ -export {}; diff --git a/web/monitor.js b/web/monitor.js index 977d957..3918c74 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1,378 +1 @@ -import { app, api } from './comfy/index.js'; -import { commonPrefix } from './common.js'; -import { MonitorUI } from './monitorUI.js'; -import { Colors } from './styles.js'; -import { convertNumberToPascalCase } from './utils.js'; -class CrystoolsMonitor { - constructor() { - Object.defineProperty(this, "idExtensionName", { - enumerable: true, - configurable: true, - writable: true, - value: 'Crystools.monitor' - }); - Object.defineProperty(this, "menuPrefix", { - enumerable: true, - configurable: true, - writable: true, - value: commonPrefix - }); - Object.defineProperty(this, "monitorUI", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "monitorGPUSettings", { - enumerable: true, - configurable: true, - writable: true, - value: [] - }); - Object.defineProperty(this, "monitorVRAMSettings", { - enumerable: true, - configurable: true, - writable: true, - value: [] - }); - Object.defineProperty(this, "monitorTemperatureSettings", { - enumerable: true, - configurable: true, - writable: true, - value: [] - }); - Object.defineProperty(this, "settingsRate", { - enumerable: true, - configurable: true, - writable: true, - value: { - id: 'Crystools.RefreshRate', - name: 'Refresh per second', - category: ['Crystools', this.menuPrefix + ' Refresh Rate'], - tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', - type: 'slider', - attrs: { - min: 0, - max: 2, - step: 0.25, - }, - defaultValue: .5, - onChange: async (value) => { - let valueNumber; - try { - valueNumber = parseFloat(value); - if (isNaN(valueNumber)) { - throw new Error('invalid value'); - } - } - catch (error) { - console.error(error); - return; - } - try { - await this.updateServer({ rate: valueNumber }); - } - catch (error) { - console.error(error); - return; - } - if (valueNumber === 0) { - this.monitorUI.updateAllMonitors({ - cpu_utilization: 0, - device: 'cpu', - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); - } - this.monitorUI?.updateAllAnimationDuration(valueNumber); - }, - } - }); - Object.defineProperty(this, "monitorCPUElement", { - enumerable: true, - configurable: true, - writable: true, - value: { - id: 'Crystools.ShowCpu', - name: 'CPU Usage', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], - type: 'boolean', - label: 'CPU', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.CPU, - onChange: async (value) => { - this.monitorUI?.updateWidget(this.monitorCPUElement); - await this.updateServer({ switchCPU: value }); - }, - } - }); - Object.defineProperty(this, "monitorRAMElement", { - enumerable: true, - configurable: true, - writable: true, - value: { - id: 'Crystools.ShowRam', - name: 'RAM Used', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], - type: 'boolean', - label: 'RAM', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.RAM, - onChange: async (value) => { - this.monitorUI?.updateWidget(this.monitorRAMElement); - await this.updateServer({ switchRAM: value }); - }, - } - }); - Object.defineProperty(this, "monitorHDDElement", { - enumerable: true, - configurable: true, - writable: true, - value: { - id: 'Crystools.ShowHdd', - name: 'Show HDD Used', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], - type: 'boolean', - label: 'HDD', - symbol: '%', - defaultValue: false, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.DISK, - onChange: async (value) => { - this.monitorUI?.updateWidget(this.monitorHDDElement); - await this.updateServer({ switchHDD: value }); - }, - } - }); - Object.defineProperty(this, "settingsHDD", { - enumerable: true, - configurable: true, - writable: true, - value: { - id: 'Crystools.WhichHdd', - name: 'Partition to show', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], - type: 'combo', - defaultValue: '/', - data: [], - options: (value) => { - const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); - return this.settingsHDD.data.map((m) => ({ - value: m, - text: m, - selected: !value ? m === which : m === value, - })); - }, - onChange: async (value) => { - await this.updateServer({ whichHDD: value }); - }, - } - }); - Object.defineProperty(this, "createSettings", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - app.ui.settings.addSetting(this.settingsRate); - app.ui.settings.addSetting(this.monitorRAMElement); - app.ui.settings.addSetting(this.monitorCPUElement); - void this.getHDDsFromServer().then((data) => { - this.settingsHDD.data = data; - app.ui.settings.addSetting(this.settingsHDD); - }); - app.ui.settings.addSetting(this.monitorHDDElement); - void this.getGPUsFromServer().then((gpus) => { - let moreThanOneGPU = false; - if (gpus.length > 1) { - moreThanOneGPU = true; - } - gpus?.forEach(({ name, index }) => { - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - let label = 'GPU'; - let labelVRAM = 'VRAM'; - let labelTemperature = 'Temp'; - if (moreThanOneGPU) { - label = 'GPU ' + index; - labelVRAM = 'VRAM' + index; - labelTemperature = 'Temp ' + index; - } - const monitorGPUNElement = { - id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), - name: ' Usage', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], - type: 'boolean', - label, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.GPU, - onChange: async (value) => { - this.monitorUI?.updateWidget(monitorGPUNElement); - void await this.updateServerGPU(index, { utilization: value }); - }, - }; - const monitorVRAMNElement = { - id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), - name: 'VRAM', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], - type: 'boolean', - label: labelVRAM, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.VRAM, - onChange: async (value) => { - this.monitorUI?.updateWidget(monitorVRAMNElement); - void await this.updateServerGPU(index, { vram: value }); - }, - }; - const monitorTemperatureNElement = { - id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), - name: 'Temperature', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], - type: 'boolean', - label: labelTemperature, - symbol: '°', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.TEMP_START, - cssColorFinal: Colors.TEMP_END, - onChange: async (value) => { - this.monitorUI?.updateWidget(monitorTemperatureNElement); - void await this.updateServerGPU(index, { temperature: value }); - }, - }; - this.monitorGPUSettings[index] = monitorGPUNElement; - this.monitorVRAMSettings[index] = monitorVRAMNElement; - this.monitorTemperatureSettings[index] = monitorTemperatureNElement; - app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); - app.ui.settings.addSetting(this.monitorVRAMSettings[index]); - app.ui.settings.addSetting(this.monitorGPUSettings[index]); - }); - }); - } - }); - Object.defineProperty(this, "updateServer", { - enumerable: true, - configurable: true, - writable: true, - value: async (data) => { - const resp = await api.fetchApi('/crystools/monitor', { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - } - }); - Object.defineProperty(this, "updateServerGPU", { - enumerable: true, - configurable: true, - writable: true, - value: async (index, data) => { - const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - } - }); - Object.defineProperty(this, "getHDDsFromServer", { - enumerable: true, - configurable: true, - writable: true, - value: async () => { - return this.getDataFromServer('HDD'); - } - }); - Object.defineProperty(this, "getGPUsFromServer", { - enumerable: true, - configurable: true, - writable: true, - value: async () => { - return this.getDataFromServer('GPU'); - } - }); - Object.defineProperty(this, "getDataFromServer", { - enumerable: true, - configurable: true, - writable: true, - value: async (what) => { - const resp = await api.fetchApi(`/crystools/monitor/${what}`, { - method: 'GET', - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.json(); - } - throw new Error(resp.statusText); - } - }); - Object.defineProperty(this, "registerListeners", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - api.addEventListener('crystools.monitor', (event) => { - if (event?.detail === undefined) { - return; - } - this.monitorUI.updateAllMonitors(event.detail); - }, false); - } - }); - this.createSettings(); - } - setup() { - const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); - this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate); - this.registerListeners(); - } -} -const crystoolsMonitor = new CrystoolsMonitor(); -app.registerExtension({ - name: crystoolsMonitor.idExtensionName, - setup: crystoolsMonitor.setup.bind(crystoolsMonitor), -}); +"use strict"; diff --git a/web/monitor.ts b/web/monitor.ts index 7e66ae9..5ce2825 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,341 +1,341 @@ -import { app, api } from './comfy/index.js'; -import { commonPrefix } from './common.js'; -import { MonitorUI } from './monitorUI.js'; -import { Colors } from './styles.js'; -import { convertNumberToPascalCase } from './utils.js'; - -class CrystoolsMonitor { - idExtensionName = 'Crystools.monitor'; - menuPrefix = commonPrefix; - - monitorUI: MonitorUI; - - monitorGPUSettings: TMonitorSettings[] = []; - monitorVRAMSettings: TMonitorSettings[] = []; - monitorTemperatureSettings: TMonitorSettings[] = []; - - settingsRate = { - id: 'Crystools.RefreshRate', - name: 'Refresh per second', - category: ['Crystools', this.menuPrefix + ' Refresh Rate'], - tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', - type: 'slider', - attrs: { - min: 0, - max: 2, - step: 0.25, - }, - defaultValue: .5, - onChange: async(value: string): Promise => { - let valueNumber: number; - - try { - valueNumber = parseFloat(value); - if (isNaN(valueNumber)) { - throw new Error('invalid value'); - } - } catch (error) { - console.error(error); - return; - } - try { - await this.updateServer({rate: valueNumber}); - } catch (error) { - console.error(error); - return; - } - - if (valueNumber === 0) { - this.monitorUI.updateAllMonitors({ - cpu_utilization: 0, - device: 'cpu', - - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); - } - - this.monitorUI?.updateAllAnimationDuration(valueNumber); - }, - }; - - - // CPU Variables - monitorCPUElement: TMonitorSettings = { - id: 'Crystools.ShowCpu', - name: 'CPU Usage', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], - type: 'boolean', - label: 'CPU', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.CPU, - onChange: async(value: boolean) => { - this.monitorUI?.updateWidget(this.monitorCPUElement); - await this.updateServer({switchCPU: value}); - }, - }; - - // RAM Variables - monitorRAMElement: TMonitorSettings = { - id: 'Crystools.ShowRam', - name: 'RAM Used', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], - type: 'boolean', - label: 'RAM', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.RAM, - onChange: async(value: boolean) => { - this.monitorUI?.updateWidget(this.monitorRAMElement); - await this.updateServer({switchRAM: value}); - }, - }; - - // HDD Variables - monitorHDDElement: TMonitorSettings = { - id: 'Crystools.ShowHdd', - name: 'Show HDD Used', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], - type: 'boolean', - label: 'HDD', - symbol: '%', - // tooltip: 'See Partition to show (HDD)', - defaultValue: false, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.DISK, - onChange: async(value: boolean) => { - this.monitorUI?.updateWidget(this.monitorHDDElement); - await this.updateServer({switchHDD: value}); - }, - }; - - settingsHDD = { - id: 'Crystools.WhichHdd', - name: 'Partition to show', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], - type: 'combo', - defaultValue: '/', - data: [], - // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? - options: (value: string): any => { - const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); - return this.settingsHDD.data.map((m) => ({ - value: m, - text: m, - selected: !value ? m === which : m === value, - })); - }, - onChange: async(value: string): Promise => { - await this.updateServer({whichHDD: value}); - }, - }; - - constructor() { - this.createSettings(); - } - - createSettings = (): void => { - app.ui.settings.addSetting(this.settingsRate); - app.ui.settings.addSetting(this.monitorRAMElement); - app.ui.settings.addSetting(this.monitorCPUElement); - - void this.getHDDsFromServer().then((data: string[]): void => { - // @ts-ignore - this.settingsHDD.data = data; - app.ui.settings.addSetting(this.settingsHDD); - }); - app.ui.settings.addSetting(this.monitorHDDElement); - - void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { - let moreThanOneGPU = false; - if (gpus.length > 1) { - moreThanOneGPU = true; - } - - gpus?.forEach(({name, index}) => { - - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - - let label = 'GPU'; - let labelVRAM = 'VRAM'; - let labelTemperature = 'Temp'; - if (moreThanOneGPU) { - label = 'GPU ' + index; - labelVRAM = 'VRAM' + index; - labelTemperature = 'Temp ' + index; - } - - // GPU Utilization Variables - const monitorGPUNElement: TMonitorSettings = { - id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), - name: ' Usage', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], - type: 'boolean', - label, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.GPU, - onChange: async(value: boolean) => { - this.monitorUI?.updateWidget(monitorGPUNElement); - void await this.updateServerGPU(index, {utilization: value}); - }, - }; - - // GPU VRAM Variables - const monitorVRAMNElement: TMonitorSettings = { - id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), - name: 'VRAM', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], - type: 'boolean', - label: labelVRAM, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.VRAM, - onChange: async(value: boolean) => { - this.monitorUI?.updateWidget(monitorVRAMNElement); - void await this.updateServerGPU(index, {vram: value}); - }, - }; - - // GPU Temperature Variables - const monitorTemperatureNElement: TMonitorSettings = { - id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), - name: 'Temperature', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], - type: 'boolean', - label: labelTemperature, - symbol: '°', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.TEMP_START, - cssColorFinal: Colors.TEMP_END, - onChange: async(value: boolean) => { - this.monitorUI?.updateWidget(monitorTemperatureNElement); - void await this.updateServerGPU(index, {temperature: value}); - }, - }; - - this.monitorGPUSettings[index] = monitorGPUNElement; - this.monitorVRAMSettings[index] = monitorVRAMNElement; - this.monitorTemperatureSettings[index] = monitorTemperatureNElement; - // @ts-ignore - app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); - // @ts-ignore - app.ui.settings.addSetting(this.monitorVRAMSettings[index]); - // @ts-ignore - app.ui.settings.addSetting(this.monitorGPUSettings[index]); - }); - }); - }; - - updateServer = async(data: TStatsSettings): Promise => { - const resp = await api.fetchApi('/crystools/monitor', { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - }; - - updateServerGPU = async(index: number, data: TGpuSettings): Promise => { - const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - }; - - getHDDsFromServer = async(): Promise => { - return this.getDataFromServer('HDD'); - }; - - getGPUsFromServer = async(): Promise => { - return this.getDataFromServer('GPU'); - }; - - getDataFromServer = async (what: string): Promise => { - const resp = await api.fetchApi(`/crystools/monitor/${what}`, { - method: 'GET', - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.json(); - } - throw new Error(resp.statusText); - }; - - setup(): void { - const currentRate = - parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); - - this.monitorUI = new MonitorUI( - this.monitorCPUElement, - this.monitorRAMElement, - this.monitorHDDElement, - this.monitorGPUSettings, - this.monitorVRAMSettings, - this.monitorTemperatureSettings, - currentRate, - ); - - this.registerListeners(); - } - - registerListeners = (): void => { - api.addEventListener('crystools.monitor', (event: CustomEvent) => { - if (event?.detail === undefined) { - return; - } - this.monitorUI.updateAllMonitors(event.detail); - }, false); - }; -} - -const crystoolsMonitor = new CrystoolsMonitor(); -app.registerExtension({ - name: crystoolsMonitor.idExtensionName, - setup: crystoolsMonitor.setup.bind(crystoolsMonitor), -}); +// import { app, api } from './comfy/index.js'; +// import { commonPrefix } from './common.js'; +// import { MonitorUI } from './monitorUI.js'; +// import { Colors } from './styles.js'; +// import { convertNumberToPascalCase } from './utils.js'; +// +// class CrystoolsMonitor { +// idExtensionName = 'Crystools.monitor'; +// menuPrefix = commonPrefix; +// +// monitorUI: MonitorUI; +// +// monitorGPUSettings: TMonitorSettings[] = []; +// monitorVRAMSettings: TMonitorSettings[] = []; +// monitorTemperatureSettings: TMonitorSettings[] = []; +// +// settingsRate = { +// id: 'Crystools.RefreshRate', +// name: 'Refresh per second', +// category: ['Crystools', this.menuPrefix + ' Refresh Rate'], +// tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', +// type: 'slider', +// attrs: { +// min: 0, +// max: 2, +// step: 0.25, +// }, +// defaultValue: .5, +// onChange: async(value: string): Promise => { +// let valueNumber: number; +// +// try { +// valueNumber = parseFloat(value); +// if (isNaN(valueNumber)) { +// throw new Error('invalid value'); +// } +// } catch (error) { +// console.error(error); +// return; +// } +// try { +// await this.updateServer({rate: valueNumber}); +// } catch (error) { +// console.error(error); +// return; +// } +// +// if (valueNumber === 0) { +// this.monitorUI.updateAllMonitors({ +// cpu_utilization: 0, +// device: 'cpu', +// +// gpus: [ +// { +// gpu_utilization: 0, +// gpu_temperature: 0, +// vram_total: 0, +// vram_used: 0, +// vram_used_percent: 0, +// }, +// ], +// hdd_total: 0, +// hdd_used: 0, +// hdd_used_percent: 0, +// ram_total: 0, +// ram_used: 0, +// ram_used_percent: 0, +// }); +// } +// +// this.monitorUI?.updateAllAnimationDuration(valueNumber); +// }, +// }; +// +// +// // CPU Variables +// monitorCPUElement: TMonitorSettings = { +// id: 'Crystools.ShowCpu', +// name: 'CPU Usage', +// category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], +// type: 'boolean', +// label: 'CPU', +// symbol: '%', +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.CPU, +// onChange: async(value: boolean) => { +// this.monitorUI?.updateWidget(this.monitorCPUElement); +// await this.updateServer({switchCPU: value}); +// }, +// }; +// +// // RAM Variables +// monitorRAMElement: TMonitorSettings = { +// id: 'Crystools.ShowRam', +// name: 'RAM Used', +// category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], +// type: 'boolean', +// label: 'RAM', +// symbol: '%', +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.RAM, +// onChange: async(value: boolean) => { +// this.monitorUI?.updateWidget(this.monitorRAMElement); +// await this.updateServer({switchRAM: value}); +// }, +// }; +// +// // HDD Variables +// monitorHDDElement: TMonitorSettings = { +// id: 'Crystools.ShowHdd', +// name: 'Show HDD Used', +// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], +// type: 'boolean', +// label: 'HDD', +// symbol: '%', +// // tooltip: 'See Partition to show (HDD)', +// defaultValue: false, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.DISK, +// onChange: async(value: boolean) => { +// this.monitorUI?.updateWidget(this.monitorHDDElement); +// await this.updateServer({switchHDD: value}); +// }, +// }; +// +// settingsHDD = { +// id: 'Crystools.WhichHdd', +// name: 'Partition to show', +// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], +// type: 'combo', +// defaultValue: '/', +// data: [], +// // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? +// options: (value: string): any => { +// const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); +// return this.settingsHDD.data.map((m) => ({ +// value: m, +// text: m, +// selected: !value ? m === which : m === value, +// })); +// }, +// onChange: async(value: string): Promise => { +// await this.updateServer({whichHDD: value}); +// }, +// }; +// +// constructor() { +// this.createSettings(); +// } +// +// createSettings = (): void => { +// app.ui.settings.addSetting(this.settingsRate); +// app.ui.settings.addSetting(this.monitorRAMElement); +// app.ui.settings.addSetting(this.monitorCPUElement); +// +// void this.getHDDsFromServer().then((data: string[]): void => { +// // @ts-ignore +// this.settingsHDD.data = data; +// app.ui.settings.addSetting(this.settingsHDD); +// }); +// app.ui.settings.addSetting(this.monitorHDDElement); +// +// void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { +// let moreThanOneGPU = false; +// if (gpus.length > 1) { +// moreThanOneGPU = true; +// } +// +// gpus?.forEach(({name, index}) => { +// +// if (name === undefined || index === undefined) { +// console.warn('getGPUsFromServer: name or index undefined', name, index); +// return; +// } +// +// let label = 'GPU'; +// let labelVRAM = 'VRAM'; +// let labelTemperature = 'Temp'; +// if (moreThanOneGPU) { +// label = 'GPU ' + index; +// labelVRAM = 'VRAM' + index; +// labelTemperature = 'Temp ' + index; +// } +// +// // GPU Utilization Variables +// const monitorGPUNElement: TMonitorSettings = { +// id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), +// name: ' Usage', +// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], +// type: 'boolean', +// label, +// symbol: '%', +// title: `${index}: ${name}`, +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.GPU, +// onChange: async(value: boolean) => { +// this.monitorUI?.updateWidget(monitorGPUNElement); +// void await this.updateServerGPU(index, {utilization: value}); +// }, +// }; +// +// // GPU VRAM Variables +// const monitorVRAMNElement: TMonitorSettings = { +// id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), +// name: 'VRAM', +// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], +// type: 'boolean', +// label: labelVRAM, +// symbol: '%', +// title: `${index}: ${name}`, +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.VRAM, +// onChange: async(value: boolean) => { +// this.monitorUI?.updateWidget(monitorVRAMNElement); +// void await this.updateServerGPU(index, {vram: value}); +// }, +// }; +// +// // GPU Temperature Variables +// const monitorTemperatureNElement: TMonitorSettings = { +// id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), +// name: 'Temperature', +// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], +// type: 'boolean', +// label: labelTemperature, +// symbol: '°', +// title: `${index}: ${name}`, +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.TEMP_START, +// cssColorFinal: Colors.TEMP_END, +// onChange: async(value: boolean) => { +// this.monitorUI?.updateWidget(monitorTemperatureNElement); +// void await this.updateServerGPU(index, {temperature: value}); +// }, +// }; +// +// this.monitorGPUSettings[index] = monitorGPUNElement; +// this.monitorVRAMSettings[index] = monitorVRAMNElement; +// this.monitorTemperatureSettings[index] = monitorTemperatureNElement; +// // @ts-ignore +// app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); +// // @ts-ignore +// app.ui.settings.addSetting(this.monitorVRAMSettings[index]); +// // @ts-ignore +// app.ui.settings.addSetting(this.monitorGPUSettings[index]); +// }); +// }); +// }; +// +// updateServer = async(data: TStatsSettings): Promise => { +// const resp = await api.fetchApi('/crystools/monitor', { +// method: 'PATCH', +// body: JSON.stringify(data), +// cache: 'no-store', +// }); +// if (resp.status === 200) { +// return await resp.text(); +// } +// throw new Error(resp.statusText); +// }; +// +// updateServerGPU = async(index: number, data: TGpuSettings): Promise => { +// const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { +// method: 'PATCH', +// body: JSON.stringify(data), +// cache: 'no-store', +// }); +// if (resp.status === 200) { +// return await resp.text(); +// } +// throw new Error(resp.statusText); +// }; +// +// getHDDsFromServer = async(): Promise => { +// return this.getDataFromServer('HDD'); +// }; +// +// getGPUsFromServer = async(): Promise => { +// return this.getDataFromServer('GPU'); +// }; +// +// getDataFromServer = async (what: string): Promise => { +// const resp = await api.fetchApi(`/crystools/monitor/${what}`, { +// method: 'GET', +// cache: 'no-store', +// }); +// if (resp.status === 200) { +// return await resp.json(); +// } +// throw new Error(resp.statusText); +// }; +// +// setup(): void { +// const currentRate = +// parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); +// +// this.monitorUI = new MonitorUI( +// this.monitorCPUElement, +// this.monitorRAMElement, +// this.monitorHDDElement, +// this.monitorGPUSettings, +// this.monitorVRAMSettings, +// this.monitorTemperatureSettings, +// currentRate, +// ); +// +// this.registerListeners(); +// } +// +// registerListeners = (): void => { +// api.addEventListener('crystools.monitor', (event: CustomEvent) => { +// if (event?.detail === undefined) { +// return; +// } +// this.monitorUI.updateAllMonitors(event.detail); +// }, false); +// }; +// } +// +// const crystoolsMonitor = new CrystoolsMonitor(); +// app.registerExtension({ +// name: crystoolsMonitor.idExtensionName, +// setup: crystoolsMonitor.setup.bind(crystoolsMonitor), +// }); diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts index 124ae33..e69de29 100644 --- a/web/monitorUI.d.ts +++ b/web/monitorUI.d.ts @@ -1,20 +0,0 @@ -import { ProgressBarUIBase } from './progressBarUI.js'; -export declare class MonitorUI extends ProgressBarUIBase { - private monitorCPUElement; - private monitorRAMElement; - private monitorHDDElement; - private monitorGPUSettings; - private monitorVRAMSettings; - private monitorTemperatureSettings; - private currentRate; - constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number); - refreshDisplay: () => void; - createDOM: () => void; - updateAllWidget: () => void; - updateWidget: (monitorSettings: TMonitorSettings) => void; - updateAllMonitors: (data: TStatsData) => void; - updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; - updateAllAnimationDuration: (value: number) => void; - updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; - createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; -} diff --git a/web/monitorUI.js b/web/monitorUI.js index 369eb30..3918c74 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,242 +1 @@ -import { app } from './comfy/index.js'; -import { ProgressBarUIBase } from './progressBarUI.js'; -export class MonitorUI extends ProgressBarUIBase { - constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { - super(); - Object.defineProperty(this, "monitorCPUElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorCPUElement - }); - Object.defineProperty(this, "monitorRAMElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorRAMElement - }); - Object.defineProperty(this, "monitorHDDElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorHDDElement - }); - Object.defineProperty(this, "monitorGPUSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorGPUSettings - }); - Object.defineProperty(this, "monitorVRAMSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorVRAMSettings - }); - Object.defineProperty(this, "monitorTemperatureSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorTemperatureSettings - }); - Object.defineProperty(this, "currentRate", { - enumerable: true, - configurable: true, - writable: true, - value: currentRate - }); - Object.defineProperty(this, "refreshDisplay", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - console.log('refreshDisplay'); - this.updateAllWidget(); - } - }); - Object.defineProperty(this, "createDOM", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); - this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); - this.monitorTemperatureSettings[index] && - this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); - }); - this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); - this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); - } - }); - Object.defineProperty(this, "updateAllWidget", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - } - }); - Object.defineProperty(this, "updateWidget", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - } - }); - Object.defineProperty(this, "updateAllMonitors", { - enumerable: true, - configurable: true, - writable: true, - value: (data) => { - this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); - if (data.gpus === undefined || data.gpus.length === 0) { - console.warn('UpdateAllMonitors: no GPU data'); - return; - } - this.monitorGPUSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.gpu_utilization); - } - else { - } - }); - this.monitorVRAMSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.vram_used_percent); - } - else { - } - }); - this.monitorTemperatureSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.gpu_temperature); - if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { - monitorSettings.htmlMonitorSliderRef.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; - } - } - else { - } - }); - } - }); - Object.defineProperty(this, "updateMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, percent) => { - if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { - return; - } - monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; - monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; - } - }); - Object.defineProperty(this, "updateAllAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - this.updatedAnimationDuration(this.monitorCPUElement, value); - this.updatedAnimationDuration(this.monitorRAMElement, value); - this.updatedAnimationDuration(this.monitorHDDElement, value); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - } - }); - Object.defineProperty(this, "updatedAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, value) => { - const slider = monitorSettings.htmlMonitorSliderRef; - if (!slider) { - return; - } - slider.style.transition = `width ${value.toFixed(1)}s`; - } - }); - Object.defineProperty(this, "createMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - if (!monitorSettings) { - return document.createElement('div'); - } - const htmlMain = document.createElement('div'); - htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.classList.add('crystools-monitor'); - monitorSettings.htmlMonitorRef = htmlMain; - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.classList.add('crystools-text'); - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.classList.add('crystools-content'); - htmlMain.append(htmlMonitorContent); - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.classList.add('crystools-slider'); - if (monitorSettings.cssColorFinal) { - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } - else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.classList.add('crystools-label'); - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - htmlMonitorLabel.innerHTML = '0%'; - return monitorSettings.htmlMonitorRef; - } - }); - this.createDOM(); - } -} +"use strict"; diff --git a/web/monitorUI.ts b/web/monitorUI.ts index 0ac0f57..49c54b1 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -1,213 +1,213 @@ -import { app } from './comfy/index.js'; -import { ProgressBarUIBase } from './progressBarUI.js'; - -export class MonitorUI extends ProgressBarUIBase { - constructor( - private monitorCPUElement: TMonitorSettings, - private monitorRAMElement: TMonitorSettings, - private monitorHDDElement: TMonitorSettings, - private monitorGPUSettings: TMonitorSettings[], - private monitorVRAMSettings: TMonitorSettings[], - private monitorTemperatureSettings: TMonitorSettings[], - private currentRate: number - ) { - super(); - this.createDOM(); - } - - refreshDisplay = (): void => { - console.log('refreshDisplay'); - this.updateAllWidget(); - }; - - override createDOM = (): void => { - this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); - - // gpu0 > gpu1 > vram0 > vram1 - // this.monitorGPUSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - // this.monitorVRAMSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - // this.monitorTemperatureSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - - // gpu0 > vram0 > gpu1 > vram1 - this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); - this.monitorTemperatureSettings[index] && - this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); - }); - - this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); - - this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); - }; - - - updateAllWidget = (): void => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - }; - - /** - * for the settings menu - * @param monitorSettings - */ - updateWidget = (monitorSettings: TMonitorSettings): void => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - }; - - updateAllMonitors = (data: TStatsData): void => { - // console.log('updateAllMonitors', data); - this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); - - if (data.gpus === undefined || data.gpus.length === 0) { - console.warn('UpdateAllMonitors: no GPU data'); - return; - } - - this.monitorGPUSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.gpu_utilization); - } else { - // console.error('UpdateAllMonitors: no GPU data for index', index); - } - }); - - this.monitorVRAMSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.vram_used_percent); - } else { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - } - }); - - this.monitorTemperatureSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.gpu_temperature); - if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ - monitorSettings.htmlMonitorSliderRef.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; - } - } else { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - } - }); - }; - - updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { - if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { - return; - } - - monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; - monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; - }; - - updateAllAnimationDuration = (value: number): void => { - this.updatedAnimationDuration(this.monitorCPUElement, value); - this.updatedAnimationDuration(this.monitorRAMElement, value); - this.updatedAnimationDuration(this.monitorHDDElement, value); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - }; - - updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { - const slider = monitorSettings.htmlMonitorSliderRef; - if (!slider) { - return; - } - - slider.style.transition = `width ${value.toFixed(1)}s`; - }; - - - createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { - if (!monitorSettings) { - // just for typescript - return document.createElement('div'); - } - const htmlMain = document.createElement('div'); - htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.classList.add('crystools-monitor'); - monitorSettings.htmlMonitorRef = htmlMain; - - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.classList.add('crystools-text'); - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.classList.add('crystools-content'); - htmlMain.append(htmlMonitorContent); - - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.classList.add('crystools-slider'); - if(monitorSettings.cssColorFinal){ - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.classList.add('crystools-label'); - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - htmlMonitorLabel.innerHTML = '0%'; - return monitorSettings.htmlMonitorRef; - }; -} +// import { app } from './comfy/index.js'; +// import { ProgressBarUIBase } from './progressBarUI.js'; +// +// export class MonitorUI extends ProgressBarUIBase { +// constructor( +// private monitorCPUElement: TMonitorSettings, +// private monitorRAMElement: TMonitorSettings, +// private monitorHDDElement: TMonitorSettings, +// private monitorGPUSettings: TMonitorSettings[], +// private monitorVRAMSettings: TMonitorSettings[], +// private monitorTemperatureSettings: TMonitorSettings[], +// private currentRate: number +// ) { +// super(); +// this.createDOM(); +// } +// +// refreshDisplay = (): void => { +// // console.log('refreshDisplay'); +// this.updateAllWidget(); +// }; +// +// override createDOM = (): void => { +// this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); +// this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); +// +// // gpu0 > gpu1 > vram0 > vram1 +// // this.monitorGPUSettings.forEach((monitorSettings) => { +// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); +// // }); +// // this.monitorVRAMSettings.forEach((monitorSettings) => { +// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); +// // }); +// // this.monitorTemperatureSettings.forEach((monitorSettings) => { +// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); +// // }); +// +// // gpu0 > vram0 > gpu1 > vram1 +// this.monitorGPUSettings.forEach((_monitorSettings, index) => { +// this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); +// this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); +// this.monitorTemperatureSettings[index] && +// this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); +// }); +// +// this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); +// +// this.updateAllAnimationDuration(this.currentRate); +// this.updateAllWidget(); +// }; +// +// +// updateAllWidget = (): void => { +// this.updateWidget(this.monitorCPUElement); +// this.updateWidget(this.monitorRAMElement); +// this.updateWidget(this.monitorHDDElement); +// +// this.monitorGPUSettings.forEach((monitorSettings) => { +// monitorSettings && this.updateWidget(monitorSettings); +// }); +// this.monitorVRAMSettings.forEach((monitorSettings) => { +// monitorSettings && this.updateWidget(monitorSettings); +// }); +// this.monitorTemperatureSettings.forEach((monitorSettings) => { +// monitorSettings && this.updateWidget(monitorSettings); +// }); +// }; +// +// /** +// * for the settings menu +// * @param monitorSettings +// */ +// updateWidget = (monitorSettings: TMonitorSettings): void => { +// const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); +// if (monitorSettings.htmlMonitorRef) { +// monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; +// } +// }; +// +// updateAllMonitors = (data: TStatsData): void => { +// // console.log('updateAllMonitors', data); +// this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); +// this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); +// this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); +// +// if (data.gpus === undefined || data.gpus.length === 0) { +// console.warn('UpdateAllMonitors: no GPU data'); +// return; +// } +// +// this.monitorGPUSettings.forEach((monitorSettings, index) => { +// if (data.gpus[index]) { +// const gpu = data.gpus[index]; +// if (gpu === undefined) { +// // console.error('UpdateAllMonitors: no GPU data for index', index); +// return; +// } +// +// this.updateMonitor(monitorSettings, gpu.gpu_utilization); +// } else { +// // console.error('UpdateAllMonitors: no GPU data for index', index); +// } +// }); +// +// this.monitorVRAMSettings.forEach((monitorSettings, index) => { +// if (data.gpus[index]) { +// const gpu = data.gpus[index]; +// if (gpu === undefined) { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// return; +// } +// +// this.updateMonitor(monitorSettings, gpu.vram_used_percent); +// } else { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// } +// }); +// +// this.monitorTemperatureSettings.forEach((monitorSettings, index) => { +// if (data.gpus[index]) { +// const gpu = data.gpus[index]; +// if (gpu === undefined) { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// return; +// } +// +// this.updateMonitor(monitorSettings, gpu.gpu_temperature); +// if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ +// monitorSettings.htmlMonitorSliderRef.style.backgroundColor = +// `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; +// } +// } else { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// } +// }); +// }; +// +// updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { +// if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { +// return; +// } +// +// monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; +// monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; +// }; +// +// updateAllAnimationDuration = (value: number): void => { +// this.updatedAnimationDuration(this.monitorCPUElement, value); +// this.updatedAnimationDuration(this.monitorRAMElement, value); +// this.updatedAnimationDuration(this.monitorHDDElement, value); +// this.monitorGPUSettings.forEach((monitorSettings) => { +// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); +// }); +// this.monitorVRAMSettings.forEach((monitorSettings) => { +// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); +// }); +// this.monitorTemperatureSettings.forEach((monitorSettings) => { +// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); +// }); +// }; +// +// updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { +// const slider = monitorSettings.htmlMonitorSliderRef; +// if (!slider) { +// return; +// } +// +// slider.style.transition = `width ${value.toFixed(1)}s`; +// }; +// +// +// createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { +// if (!monitorSettings) { +// // just for typescript +// return document.createElement('div'); +// } +// const htmlMain = document.createElement('div'); +// htmlMain.setAttribute('id', monitorSettings.id); +// htmlMain.classList.add('crystools-monitor'); +// monitorSettings.htmlMonitorRef = htmlMain; +// +// if (monitorSettings.title) { +// htmlMain.title = monitorSettings.title; +// } +// +// const htmlMonitorText = document.createElement('div'); +// htmlMonitorText.classList.add('crystools-text'); +// htmlMonitorText.innerHTML = monitorSettings.label; +// htmlMain.append(htmlMonitorText); +// +// const htmlMonitorContent = document.createElement('div'); +// htmlMonitorContent.classList.add('crystools-content'); +// htmlMain.append(htmlMonitorContent); +// +// const htmlMonitorSlider = document.createElement('div'); +// htmlMonitorSlider.classList.add('crystools-slider'); +// if(monitorSettings.cssColorFinal){ +// htmlMonitorSlider.style.backgroundColor = +// `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; +// } else { +// htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; +// } +// monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; +// htmlMonitorContent.append(htmlMonitorSlider); +// +// const htmlMonitorLabel = document.createElement('div'); +// htmlMonitorLabel.classList.add('crystools-label'); +// monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; +// htmlMonitorContent.append(htmlMonitorLabel); +// htmlMonitorLabel.innerHTML = '0%'; +// return monitorSettings.htmlMonitorRef; +// }; +// } diff --git a/web/progressBar.js b/web/progressBar.js index 98c8699..07ac324 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -1,6 +1,6 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; -import { EStatus, ProgressBarUI } from './progressBarUI.js'; +import { EStatus, NewMenuOptions, ProgressBarUI } from './progressBarUI.js'; class CrystoolsProgressBar { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -33,6 +33,12 @@ class CrystoolsProgressBar { writable: true, value: 'crystools-progress-bar-container' }); + Object.defineProperty(this, "newMenu", { + enumerable: true, + configurable: true, + writable: true, + value: NewMenuOptions.Disabled + }); Object.defineProperty(this, "currentStatus", { enumerable: true, configurable: true, @@ -84,6 +90,7 @@ class CrystoolsProgressBar { id: this.idShowProgressBar, name: 'Show progress bar', category: ['Crystools', this.menuPrefix + ' Progress Bar', 'Show'], + tooltip: 'This apply only on old menu', type: 'boolean', defaultValue: this.defaultShowStatus, onChange: this.showProgressBar, @@ -95,9 +102,12 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: (value) => { - const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); - if (container) { - container.style.display = value ? 'block' : 'none'; + console.log('showProgressBar', value, this.newMenu); + if (this.newMenu === NewMenuOptions.Disabled) { + const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); + if (container) { + container.style.display = value ? 'block' : 'none'; + } } } }); @@ -106,7 +116,21 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: () => { - this.progressBarVertical.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + console.log('updateDisplay'); + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + switch (this.newMenu) { + case NewMenuOptions.Disabled: + this.setup(); + break; + default: + console.log('new menu', this.newMenu); + } + } + if (this.newMenu === NewMenuOptions.Disabled) { + this.progressBarVertical?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + } } }); Object.defineProperty(this, "registerListeners", { @@ -164,9 +188,19 @@ class CrystoolsProgressBar { app.canvas.centerOnNode(node); } }); + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); this.createSettings(); + this.updateDisplay(); + window.addEventListener('resize', () => this.updateDisplay()); } setup() { + if (this.progressBarVertical) { + this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); + return; + } + if (this.newMenu !== NewMenuOptions.Disabled) { + return; + } this.progressBarVertical = new ProgressBarUI(this.htmlIdCrystoolsProgressBarContainer, this.centerNode); this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; diff --git a/web/progressBar.ts b/web/progressBar.ts index 1bf03ae..797c280 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -1,6 +1,6 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; -import { EStatus, ProgressBarUI } from './progressBarUI.js'; +import { EStatus, NewMenuOptions, ProgressBarUI } from './progressBarUI.js'; class CrystoolsProgressBar { idExtensionName = 'Crystools.progressBar'; @@ -8,6 +8,7 @@ class CrystoolsProgressBar { defaultShowStatus = true; menuPrefix = commonPrefix; htmlIdCrystoolsProgressBarContainer = 'crystools-progress-bar-container'; + newMenu: NewMenuOptions = NewMenuOptions.Disabled; currentStatus = EStatus.executed; currentProgress = 0; @@ -20,15 +21,19 @@ class CrystoolsProgressBar { progressBarVertical: ProgressBarUI; constructor() { + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); this.createSettings(); + this.updateDisplay(); + window.addEventListener('resize', () => this.updateDisplay()); } - // not on setup because this affect the order on settings, I prefer to options at first + // not on setup because this affect the order on settings, I prefer to options at first createSettings = (): void => { app.ui.settings.addSetting({ id: this.idShowProgressBar, name: 'Show progress bar', - category: ['Crystools', this.menuPrefix + ' Progress Bar', 'Show' ], + category: ['Crystools', this.menuPrefix + ' Progress Bar', 'Show'], + tooltip: 'This apply only on old menu', type: 'boolean', defaultValue: this.defaultShowStatus, onChange: this.showProgressBar, @@ -36,19 +41,49 @@ class CrystoolsProgressBar { }; showProgressBar = (value: boolean): void => { - const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); + console.log('showProgressBar', value, this.newMenu); + if (this.newMenu === NewMenuOptions.Disabled) { + const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); - // validation because this run before setup - if (container) { - container.style.display = value ? 'block' : 'none'; + // validation because this run before setup + if (container) { + container.style.display = value ? 'block' : 'none'; + } } + }; updateDisplay = (): void => { - this.progressBarVertical.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + console.log('updateDisplay'); + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + + switch (this.newMenu) { + case NewMenuOptions.Disabled: + this.setup(); + break; + default: + console.log('new menu', this.newMenu); + } + } + + if (this.newMenu === NewMenuOptions.Disabled) { + this.progressBarVertical?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + } + }; setup(): void { + if (this.progressBarVertical) { + this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); + return; + } + if (this.newMenu !== NewMenuOptions.Disabled) { + return; + } + this.progressBarVertical = new ProgressBarUI( this.htmlIdCrystoolsProgressBarContainer, this.centerNode); @@ -61,7 +96,7 @@ class CrystoolsProgressBar { } registerListeners = (): void => { - api.addEventListener('status', ({ detail }: any) => { + api.addEventListener('status', ({detail}: any) => { this.currentStatus = this.currentStatus === EStatus.execution_error ? EStatus.execution_error : EStatus.executed; const queueRemaining = detail?.exec_info.queue_remaining; @@ -71,8 +106,8 @@ class CrystoolsProgressBar { this.updateDisplay(); }, false); - api.addEventListener('progress', ({ detail }: any) => { - const { value, max, node } = detail; + api.addEventListener('progress', ({detail}: any) => { + const {value, max, node} = detail; const progress = Math.floor((value / max) * 100); if (!isNaN(progress) && progress >= 0 && progress <= 100) { @@ -83,7 +118,7 @@ class CrystoolsProgressBar { this.updateDisplay(); }, false); - api.addEventListener('executed', ({ detail }: any) => { + api.addEventListener('executed', ({detail}: any) => { if (detail?.node) { this.currentNode = detail.node; } @@ -91,14 +126,14 @@ class CrystoolsProgressBar { this.updateDisplay(); }, false); - api.addEventListener('execution_start', ({ _detail }: any) => { + api.addEventListener('execution_start', ({_detail}: any) => { this.currentStatus = EStatus.executing; this.timeStart = Date.now(); this.updateDisplay(); }, false); - api.addEventListener('execution_error', ({ _detail }: any) => { + api.addEventListener('execution_error', ({_detail}: any) => { this.currentStatus = EStatus.execution_error; this.updateDisplay(); diff --git a/web/progressBarUI.d.ts b/web/progressBarUI.d.ts index 9ec0ed3..b4fd5a3 100644 --- a/web/progressBarUI.d.ts +++ b/web/progressBarUI.d.ts @@ -3,13 +3,18 @@ export declare enum EStatus { executed = "Executed", execution_error = "Execution error" } +export declare enum NewMenuOptions { + 'Disabled' = "Disabled", + 'Top' = "Top", + 'Bottom' = "Bottom" +} export declare abstract class ProgressBarUIBase { protected htmlIdCrystoolsRoot: string; protected htmlClassCrystoolsMonitorContainer: string; protected htmlContainer: HTMLDivElement; + protected newMenu: NewMenuOptions; protected constructor(); createRoot(): void; - abstract refreshDisplay(): void; abstract createDOM(): void; } export declare class ProgressBarUI extends ProgressBarUIBase { diff --git a/web/progressBarUI.js b/web/progressBarUI.js index a5769d2..e78f32e 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,9 +1,16 @@ +import { app } from './comfy/index.js'; export var EStatus; (function (EStatus) { EStatus["executing"] = "Executing"; EStatus["executed"] = "Executed"; EStatus["execution_error"] = "Execution error"; })(EStatus || (EStatus = {})); +export var NewMenuOptions; +(function (NewMenuOptions) { + NewMenuOptions["Disabled"] = "Disabled"; + NewMenuOptions["Top"] = "Top"; + NewMenuOptions["Bottom"] = "Bottom"; +})(NewMenuOptions || (NewMenuOptions = {})); export class ProgressBarUIBase { constructor() { Object.defineProperty(this, "htmlIdCrystoolsRoot", { @@ -24,8 +31,17 @@ export class ProgressBarUIBase { writable: true, value: void 0 }); - this.createRoot(); - window.addEventListener('resize', () => this.refreshDisplay()); + Object.defineProperty(this, "newMenu", { + enumerable: true, + configurable: true, + writable: true, + value: NewMenuOptions.Disabled + }); + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + console.log('menu', this.newMenu); + if (this.newMenu === NewMenuOptions.Disabled) { + this.createRoot(); + } } createRoot() { let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); @@ -90,6 +106,7 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: () => { + console.log('create'); const htmlContainer = document.createElement('div'); htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); @@ -115,7 +132,13 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: () => { - this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + console.log('dddd', this.newMenu); + if (this.newMenu === NewMenuOptions.Disabled) { + this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + } + else { + console.log('refresh'); + } } }); Object.defineProperty(this, "updateDisplay", { @@ -123,6 +146,7 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: (currentStatus, timeStart, currentProgress) => { + console.log('entra'); if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); return; @@ -149,6 +173,8 @@ export class ProgressBarUI extends ProgressBarUIBase { } } }); - this.createDOM(); + if (this.newMenu === NewMenuOptions.Disabled) { + this.createDOM(); + } } } diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index f826eac..ad92368 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -1,4 +1,4 @@ -// import { app } from './comfy/index.js'; +import { app } from './comfy/index.js'; export enum EStatus { executing = 'Executing', @@ -6,14 +6,25 @@ export enum EStatus { execution_error = 'Execution error', } +export enum NewMenuOptions { + 'Disabled' = 'Disabled', + 'Top' = 'Top', + 'Bottom' = 'Bottom', +} + export abstract class ProgressBarUIBase { protected htmlIdCrystoolsRoot = 'crystools-root'; protected htmlClassCrystoolsMonitorContainer = 'crystools-monitor-container'; protected htmlContainer: HTMLDivElement; + protected newMenu: NewMenuOptions = NewMenuOptions.Disabled; protected constructor() { - this.createRoot(); - window.addEventListener('resize', () => this.refreshDisplay()); + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + console.log('menu', this.newMenu); + if(this.newMenu === NewMenuOptions.Disabled) { + this.createRoot(); + } + // window.addEventListener('resize', () => this.refreshDisplay()); } createRoot(): void { @@ -33,7 +44,7 @@ export abstract class ProgressBarUIBase { ctoolsRoot.append(this.htmlContainer); } - abstract refreshDisplay(): void; + // abstract refreshDisplay(): void; abstract createDOM(): void; } @@ -49,10 +60,13 @@ export class ProgressBarUI extends ProgressBarUIBase{ private centerNode: () => void ) { super(); - this.createDOM(); + if(this.newMenu === NewMenuOptions.Disabled) { + this.createDOM(); + } } createDOM = (): void => { + console.log('create'); const htmlContainer = document.createElement('div'); htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); @@ -77,10 +91,16 @@ export class ProgressBarUI extends ProgressBarUIBase{ }; refreshDisplay = (): void => { - this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + console.log('dddd', this.newMenu); + if(this.newMenu === NewMenuOptions.Disabled) { + this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + } else { + console.log('refresh'); + } }; updateDisplay = (currentStatus: EStatus, timeStart: number, currentProgress: number): void => { + console.log('entra'); if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); return; @@ -90,9 +110,6 @@ export class ProgressBarUI extends ProgressBarUIBase{ this.timeStart = timeStart; this.currentProgress = currentProgress; - // TODO from here! - // const menu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - // console.log('menu', menu); if (currentStatus === EStatus.executed) { // finished From 48cfffbd44d71a615b332409dbd65a68f766d442 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sun, 22 Sep 2024 00:52:35 +0200 Subject: [PATCH 14/31] starting with horizontal... finally2 --- web/monitor.d.ts | 1 + web/monitor.js | 446 +++++++++++++++++++++++++- web/monitor.ts | 727 +++++++++++++++++++++++-------------------- web/monitorUI.d.ts | 20 ++ web/monitorUI.js | 242 +++++++++++++- web/monitorUI.ts | 426 ++++++++++++------------- web/progressBar.js | 3 - web/progressBar.ts | 4 +- web/progressBarUI.js | 2 - web/progressBarUI.ts | 3 - web/types.d.ts | 7 +- 11 files changed, 1311 insertions(+), 570 deletions(-) diff --git a/web/monitor.d.ts b/web/monitor.d.ts index e69de29..cb0ff5c 100644 --- a/web/monitor.d.ts +++ b/web/monitor.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/web/monitor.js b/web/monitor.js index 3918c74..c27a23b 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1 +1,445 @@ -"use strict"; +import { app, api } from './comfy/index.js'; +import { commonPrefix } from './common.js'; +import { MonitorUI } from './monitorUI.js'; +import { Colors } from './styles.js'; +import { convertNumberToPascalCase } from './utils.js'; +class CrystoolsMonitor { + constructor() { + Object.defineProperty(this, "idExtensionName", { + enumerable: true, + configurable: true, + writable: true, + value: 'Crystools.monitor' + }); + Object.defineProperty(this, "menuPrefix", { + enumerable: true, + configurable: true, + writable: true, + value: commonPrefix + }); + Object.defineProperty(this, "monitorUI", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "settingsRate", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorCPUElement", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorRAMElement", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorHDDElement", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "settingsHDD", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorGPUSettings", { + enumerable: true, + configurable: true, + writable: true, + value: [] + }); + Object.defineProperty(this, "monitorVRAMSettings", { + enumerable: true, + configurable: true, + writable: true, + value: [] + }); + Object.defineProperty(this, "monitorTemperatureSettings", { + enumerable: true, + configurable: true, + writable: true, + value: [] + }); + Object.defineProperty(this, "createSettingsRate", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.settingsRate = { + id: 'Crystools.RefreshRate', + name: 'Refresh per second', + category: ['Crystools', this.menuPrefix + ' Refresh Rate'], + tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', + type: 'slider', + attrs: { + min: 0, + max: 2, + step: 0.25, + }, + defaultValue: .5, + onChange: async (value) => { + let valueNumber; + try { + valueNumber = parseFloat(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } + catch (error) { + console.error(error); + return; + } + try { + await this.updateServer({ rate: valueNumber }); + } + catch (error) { + console.error(error); + return; + } + if (valueNumber === 0) { + this.monitorUI.updateAllMonitors({ + cpu_utilization: 0, + device: 'cpu', + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }); + } + this.monitorUI?.updateAllAnimationDuration(valueNumber); + }, + }; + } + }); + Object.defineProperty(this, "createSettingsCPU", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.monitorCPUElement = { + id: 'Crystools.ShowCpu', + name: 'CPU Usage', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], + type: 'boolean', + label: 'CPU', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.CPU, + onChange: async (value) => { + this.monitorUI?.updateWidget(this.monitorCPUElement); + await this.updateServer({ switchCPU: value }); + }, + }; + } + }); + Object.defineProperty(this, "createSettingsRAM", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.monitorRAMElement = { + id: 'Crystools.ShowRam', + name: 'RAM Used', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], + type: 'boolean', + label: 'RAM', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.RAM, + onChange: async (value) => { + this.monitorUI?.updateWidget(this.monitorRAMElement); + await this.updateServer({ switchRAM: value }); + }, + }; + } + }); + Object.defineProperty(this, "createSettingsGPUUsage", { + enumerable: true, + configurable: true, + writable: true, + value: (name, index, moreThanOneGPU) => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + let label = 'GPU '; + label += moreThanOneGPU ? index : ''; + const monitorGPUNElement = { + id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), + name: ' Usage', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], + type: 'boolean', + label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.GPU, + onChange: async (value) => { + this.monitorUI?.updateWidget(monitorGPUNElement); + void await this.updateServerGPU(index, { utilization: value }); + }, + }; + this.monitorGPUSettings[index] = monitorGPUNElement; + app.ui.settings.addSetting(this.monitorGPUSettings[index]); + } + }); + Object.defineProperty(this, "createSettingsGPUVRAM", { + enumerable: true, + configurable: true, + writable: true, + value: (name, index, moreThanOneGPU) => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + let label = 'VRAM'; + label += moreThanOneGPU ? index : ''; + const monitorVRAMNElement = { + id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), + name: 'VRAM', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], + type: 'boolean', + label: label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.VRAM, + onChange: async (value) => { + this.monitorUI?.updateWidget(monitorVRAMNElement); + void await this.updateServerGPU(index, { vram: value }); + }, + }; + this.monitorVRAMSettings[index] = monitorVRAMNElement; + app.ui.settings.addSetting(this.monitorVRAMSettings[index]); + } + }); + Object.defineProperty(this, "createSettingsGPUTemp", { + enumerable: true, + configurable: true, + writable: true, + value: (name, index, moreThanOneGPU) => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + let label = 'Temp '; + label += moreThanOneGPU ? index : ''; + const monitorTemperatureNElement = { + id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), + name: 'Temperature', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], + type: 'boolean', + label: label, + symbol: '°', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.TEMP_START, + cssColorFinal: Colors.TEMP_END, + onChange: async (value) => { + this.monitorUI?.updateWidget(monitorTemperatureNElement); + void await this.updateServerGPU(index, { temperature: value }); + }, + }; + this.monitorTemperatureSettings[index] = monitorTemperatureNElement; + app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); + } + }); + Object.defineProperty(this, "createSettingsHDD", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.monitorHDDElement = { + id: 'Crystools.ShowHdd', + name: 'Show HDD Used', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], + type: 'boolean', + label: 'HDD', + symbol: '%', + defaultValue: false, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.DISK, + onChange: async (value) => { + this.monitorUI?.updateWidget(this.monitorHDDElement); + await this.updateServer({ switchHDD: value }); + }, + }; + this.settingsHDD = { + id: 'Crystools.WhichHdd', + name: 'Partition to show', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], + type: 'combo', + defaultValue: '/', + data: [], + options: (value) => { + const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); + return this.settingsHDD.data.map((m) => ({ + value: m, + text: m, + selected: !value ? m === which : m === value, + })); + }, + onChange: async (value) => { + await this.updateServer({ whichHDD: value }); + }, + }; + } + }); + Object.defineProperty(this, "createSettings", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + app.ui.settings.addSetting(this.settingsRate); + app.ui.settings.addSetting(this.monitorRAMElement); + app.ui.settings.addSetting(this.monitorCPUElement); + void this.getHDDsFromServer().then((data) => { + this.settingsHDD.data = data; + app.ui.settings.addSetting(this.settingsHDD); + }); + app.ui.settings.addSetting(this.monitorHDDElement); + void this.getGPUsFromServer().then((gpus) => { + let moreThanOneGPU = false; + if (gpus.length > 1) { + moreThanOneGPU = true; + } + gpus?.forEach(({ name, index }) => { + this.createSettingsGPUTemp(name, index, moreThanOneGPU); + this.createSettingsGPUVRAM(name, index, moreThanOneGPU); + this.createSettingsGPUUsage(name, index, moreThanOneGPU); + }); + }); + } + }); + Object.defineProperty(this, "updateServer", { + enumerable: true, + configurable: true, + writable: true, + value: async (data) => { + const resp = await api.fetchApi('/crystools/monitor', { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + } + }); + Object.defineProperty(this, "updateServerGPU", { + enumerable: true, + configurable: true, + writable: true, + value: async (index, data) => { + const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + } + }); + Object.defineProperty(this, "getHDDsFromServer", { + enumerable: true, + configurable: true, + writable: true, + value: async () => { + return this.getDataFromServer('HDD'); + } + }); + Object.defineProperty(this, "getGPUsFromServer", { + enumerable: true, + configurable: true, + writable: true, + value: async () => { + return this.getDataFromServer('GPU'); + } + }); + Object.defineProperty(this, "getDataFromServer", { + enumerable: true, + configurable: true, + writable: true, + value: async (what) => { + const resp = await api.fetchApi(`/crystools/monitor/${what}`, { + method: 'GET', + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.json(); + } + throw new Error(resp.statusText); + } + }); + Object.defineProperty(this, "registerListeners", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + api.addEventListener('crystools.monitor', (event) => { + if (event?.detail === undefined) { + return; + } + this.monitorUI.updateAllMonitors(event.detail); + }, false); + } + }); + this.createSettingsRate(); + this.createSettingsCPU(); + this.createSettingsRAM(); + this.createSettingsHDD(); + this.createSettings(); + } + setup() { + const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); + this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate); + this.registerListeners(); + } +} +const crystoolsMonitor = new CrystoolsMonitor(); +app.registerExtension({ + name: crystoolsMonitor.idExtensionName, + setup: crystoolsMonitor.setup.bind(crystoolsMonitor), +}); diff --git a/web/monitor.ts b/web/monitor.ts index 5ce2825..ce141e1 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,341 +1,386 @@ -// import { app, api } from './comfy/index.js'; -// import { commonPrefix } from './common.js'; -// import { MonitorUI } from './monitorUI.js'; -// import { Colors } from './styles.js'; -// import { convertNumberToPascalCase } from './utils.js'; -// -// class CrystoolsMonitor { -// idExtensionName = 'Crystools.monitor'; -// menuPrefix = commonPrefix; -// -// monitorUI: MonitorUI; -// -// monitorGPUSettings: TMonitorSettings[] = []; -// monitorVRAMSettings: TMonitorSettings[] = []; -// monitorTemperatureSettings: TMonitorSettings[] = []; -// -// settingsRate = { -// id: 'Crystools.RefreshRate', -// name: 'Refresh per second', -// category: ['Crystools', this.menuPrefix + ' Refresh Rate'], -// tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', -// type: 'slider', -// attrs: { -// min: 0, -// max: 2, -// step: 0.25, -// }, -// defaultValue: .5, -// onChange: async(value: string): Promise => { -// let valueNumber: number; -// -// try { -// valueNumber = parseFloat(value); -// if (isNaN(valueNumber)) { -// throw new Error('invalid value'); -// } -// } catch (error) { -// console.error(error); -// return; -// } -// try { -// await this.updateServer({rate: valueNumber}); -// } catch (error) { -// console.error(error); -// return; -// } -// -// if (valueNumber === 0) { -// this.monitorUI.updateAllMonitors({ -// cpu_utilization: 0, -// device: 'cpu', -// -// gpus: [ -// { -// gpu_utilization: 0, -// gpu_temperature: 0, -// vram_total: 0, -// vram_used: 0, -// vram_used_percent: 0, -// }, -// ], -// hdd_total: 0, -// hdd_used: 0, -// hdd_used_percent: 0, -// ram_total: 0, -// ram_used: 0, -// ram_used_percent: 0, -// }); -// } -// -// this.monitorUI?.updateAllAnimationDuration(valueNumber); -// }, -// }; -// -// -// // CPU Variables -// monitorCPUElement: TMonitorSettings = { -// id: 'Crystools.ShowCpu', -// name: 'CPU Usage', -// category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], -// type: 'boolean', -// label: 'CPU', -// symbol: '%', -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.CPU, -// onChange: async(value: boolean) => { -// this.monitorUI?.updateWidget(this.monitorCPUElement); -// await this.updateServer({switchCPU: value}); -// }, -// }; -// -// // RAM Variables -// monitorRAMElement: TMonitorSettings = { -// id: 'Crystools.ShowRam', -// name: 'RAM Used', -// category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], -// type: 'boolean', -// label: 'RAM', -// symbol: '%', -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.RAM, -// onChange: async(value: boolean) => { -// this.monitorUI?.updateWidget(this.monitorRAMElement); -// await this.updateServer({switchRAM: value}); -// }, -// }; -// -// // HDD Variables -// monitorHDDElement: TMonitorSettings = { -// id: 'Crystools.ShowHdd', -// name: 'Show HDD Used', -// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], -// type: 'boolean', -// label: 'HDD', -// symbol: '%', -// // tooltip: 'See Partition to show (HDD)', -// defaultValue: false, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.DISK, -// onChange: async(value: boolean) => { -// this.monitorUI?.updateWidget(this.monitorHDDElement); -// await this.updateServer({switchHDD: value}); -// }, -// }; -// -// settingsHDD = { -// id: 'Crystools.WhichHdd', -// name: 'Partition to show', -// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], -// type: 'combo', -// defaultValue: '/', -// data: [], -// // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? -// options: (value: string): any => { -// const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); -// return this.settingsHDD.data.map((m) => ({ -// value: m, -// text: m, -// selected: !value ? m === which : m === value, -// })); -// }, -// onChange: async(value: string): Promise => { -// await this.updateServer({whichHDD: value}); -// }, -// }; -// -// constructor() { -// this.createSettings(); -// } -// -// createSettings = (): void => { -// app.ui.settings.addSetting(this.settingsRate); -// app.ui.settings.addSetting(this.monitorRAMElement); -// app.ui.settings.addSetting(this.monitorCPUElement); -// -// void this.getHDDsFromServer().then((data: string[]): void => { -// // @ts-ignore -// this.settingsHDD.data = data; -// app.ui.settings.addSetting(this.settingsHDD); -// }); -// app.ui.settings.addSetting(this.monitorHDDElement); -// -// void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { -// let moreThanOneGPU = false; -// if (gpus.length > 1) { -// moreThanOneGPU = true; -// } -// -// gpus?.forEach(({name, index}) => { -// -// if (name === undefined || index === undefined) { -// console.warn('getGPUsFromServer: name or index undefined', name, index); -// return; -// } -// -// let label = 'GPU'; -// let labelVRAM = 'VRAM'; -// let labelTemperature = 'Temp'; -// if (moreThanOneGPU) { -// label = 'GPU ' + index; -// labelVRAM = 'VRAM' + index; -// labelTemperature = 'Temp ' + index; -// } -// -// // GPU Utilization Variables -// const monitorGPUNElement: TMonitorSettings = { -// id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), -// name: ' Usage', -// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], -// type: 'boolean', -// label, -// symbol: '%', -// title: `${index}: ${name}`, -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.GPU, -// onChange: async(value: boolean) => { -// this.monitorUI?.updateWidget(monitorGPUNElement); -// void await this.updateServerGPU(index, {utilization: value}); -// }, -// }; -// -// // GPU VRAM Variables -// const monitorVRAMNElement: TMonitorSettings = { -// id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), -// name: 'VRAM', -// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], -// type: 'boolean', -// label: labelVRAM, -// symbol: '%', -// title: `${index}: ${name}`, -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.VRAM, -// onChange: async(value: boolean) => { -// this.monitorUI?.updateWidget(monitorVRAMNElement); -// void await this.updateServerGPU(index, {vram: value}); -// }, -// }; -// -// // GPU Temperature Variables -// const monitorTemperatureNElement: TMonitorSettings = { -// id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), -// name: 'Temperature', -// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], -// type: 'boolean', -// label: labelTemperature, -// symbol: '°', -// title: `${index}: ${name}`, -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.TEMP_START, -// cssColorFinal: Colors.TEMP_END, -// onChange: async(value: boolean) => { -// this.monitorUI?.updateWidget(monitorTemperatureNElement); -// void await this.updateServerGPU(index, {temperature: value}); -// }, -// }; -// -// this.monitorGPUSettings[index] = monitorGPUNElement; -// this.monitorVRAMSettings[index] = monitorVRAMNElement; -// this.monitorTemperatureSettings[index] = monitorTemperatureNElement; -// // @ts-ignore -// app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); -// // @ts-ignore -// app.ui.settings.addSetting(this.monitorVRAMSettings[index]); -// // @ts-ignore -// app.ui.settings.addSetting(this.monitorGPUSettings[index]); -// }); -// }); -// }; -// -// updateServer = async(data: TStatsSettings): Promise => { -// const resp = await api.fetchApi('/crystools/monitor', { -// method: 'PATCH', -// body: JSON.stringify(data), -// cache: 'no-store', -// }); -// if (resp.status === 200) { -// return await resp.text(); -// } -// throw new Error(resp.statusText); -// }; -// -// updateServerGPU = async(index: number, data: TGpuSettings): Promise => { -// const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { -// method: 'PATCH', -// body: JSON.stringify(data), -// cache: 'no-store', -// }); -// if (resp.status === 200) { -// return await resp.text(); -// } -// throw new Error(resp.statusText); -// }; -// -// getHDDsFromServer = async(): Promise => { -// return this.getDataFromServer('HDD'); -// }; -// -// getGPUsFromServer = async(): Promise => { -// return this.getDataFromServer('GPU'); -// }; -// -// getDataFromServer = async (what: string): Promise => { -// const resp = await api.fetchApi(`/crystools/monitor/${what}`, { -// method: 'GET', -// cache: 'no-store', -// }); -// if (resp.status === 200) { -// return await resp.json(); -// } -// throw new Error(resp.statusText); -// }; -// -// setup(): void { -// const currentRate = -// parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); -// -// this.monitorUI = new MonitorUI( -// this.monitorCPUElement, -// this.monitorRAMElement, -// this.monitorHDDElement, -// this.monitorGPUSettings, -// this.monitorVRAMSettings, -// this.monitorTemperatureSettings, -// currentRate, -// ); -// -// this.registerListeners(); -// } -// -// registerListeners = (): void => { -// api.addEventListener('crystools.monitor', (event: CustomEvent) => { -// if (event?.detail === undefined) { -// return; -// } -// this.monitorUI.updateAllMonitors(event.detail); -// }, false); -// }; -// } -// -// const crystoolsMonitor = new CrystoolsMonitor(); -// app.registerExtension({ -// name: crystoolsMonitor.idExtensionName, -// setup: crystoolsMonitor.setup.bind(crystoolsMonitor), -// }); +import { app, api } from './comfy/index.js'; +import { commonPrefix } from './common.js'; +import { MonitorUI } from './monitorUI.js'; +import { Colors } from './styles.js'; +import { convertNumberToPascalCase } from './utils.js'; + +class CrystoolsMonitor { + idExtensionName = 'Crystools.monitor'; + menuPrefix = commonPrefix; + + monitorUI: MonitorUI; + + settingsRate: TMonitorSettings; + monitorCPUElement: TMonitorSettings; + monitorRAMElement: TMonitorSettings; + monitorHDDElement: TMonitorSettings; + settingsHDD: TMonitorSettings; + monitorGPUSettings: TMonitorSettings[] = []; + monitorVRAMSettings: TMonitorSettings[] = []; + monitorTemperatureSettings: TMonitorSettings[] = []; + + + constructor() { + this.createSettingsRate(); + this.createSettingsCPU(); + this.createSettingsRAM(); + this.createSettingsHDD(); + this.createSettings(); + } + + createSettingsRate = (): void => { + this.settingsRate = { + id: 'Crystools.RefreshRate', + name: 'Refresh per second', + category: ['Crystools', this.menuPrefix + ' Refresh Rate'], + tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', + type: 'slider', + attrs: { + min: 0, + max: 2, + step: 0.25, + }, + defaultValue: .5, + // @ts-ignore + onChange: async(value: string): Promise => { + let valueNumber: number; + + try { + valueNumber = parseFloat(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } catch (error) { + console.error(error); + return; + } + try { + await this.updateServer({rate: valueNumber}); + } catch (error) { + console.error(error); + return; + } + + if (valueNumber === 0) { + this.monitorUI.updateAllMonitors({ + cpu_utilization: 0, + device: 'cpu', + + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }); + } + + this.monitorUI?.updateAllAnimationDuration(valueNumber); + }, + }; + }; + + createSettingsCPU = (): void => { + // CPU Variables + this.monitorCPUElement = { + id: 'Crystools.ShowCpu', + name: 'CPU Usage', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], + type: 'boolean', + label: 'CPU', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.CPU, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorUI?.updateWidget(this.monitorCPUElement); + await this.updateServer({switchCPU: value}); + }, + }; + }; + + createSettingsRAM = (): void => { + // RAM Variables + this.monitorRAMElement = { + id: 'Crystools.ShowRam', + name: 'RAM Used', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], + type: 'boolean', + label: 'RAM', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.RAM, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorUI?.updateWidget(this.monitorRAMElement); + await this.updateServer({switchRAM: value}); + }, + }; + }; + + createSettingsGPUUsage = (name: string, index: number, moreThanOneGPU: boolean): void => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + + let label = 'GPU '; + label += moreThanOneGPU ? index : ''; + + const monitorGPUNElement: TMonitorSettings = { + id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), + name: ' Usage', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], + type: 'boolean', + label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.GPU, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorUI?.updateWidget(monitorGPUNElement); + void await this.updateServerGPU(index, {utilization: value}); + }, + }; + + this.monitorGPUSettings[index] = monitorGPUNElement; + app.ui.settings.addSetting(this.monitorGPUSettings[index]); + }; + + createSettingsGPUVRAM = (name: string, index: number, moreThanOneGPU: boolean): void => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + + let label = 'VRAM'; + label += moreThanOneGPU ? index : ''; + + // GPU VRAM Variables + const monitorVRAMNElement: TMonitorSettings = { + id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), + name: 'VRAM', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], + type: 'boolean', + label: label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.VRAM, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorUI?.updateWidget(monitorVRAMNElement); + void await this.updateServerGPU(index, {vram: value}); + }, + }; + + this.monitorVRAMSettings[index] = monitorVRAMNElement; + app.ui.settings.addSetting(this.monitorVRAMSettings[index]); + }; + + createSettingsGPUTemp = (name: string, index: number, moreThanOneGPU: boolean): void => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + + let label = 'Temp '; + label += moreThanOneGPU ? index : ''; + + // GPU Temperature Variables + const monitorTemperatureNElement: TMonitorSettings = { + id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), + name: 'Temperature', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], + type: 'boolean', + label: label, + symbol: '°', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.TEMP_START, + cssColorFinal: Colors.TEMP_END, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorUI?.updateWidget(monitorTemperatureNElement); + void await this.updateServerGPU(index, {temperature: value}); + }, + }; + + this.monitorTemperatureSettings[index] = monitorTemperatureNElement; + app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); + }; + + createSettingsHDD = (): void => { + // HDD Variables + this.monitorHDDElement = { + id: 'Crystools.ShowHdd', + name: 'Show HDD Used', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], + type: 'boolean', + label: 'HDD', + symbol: '%', + // tooltip: 'See Partition to show (HDD)', + defaultValue: false, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.DISK, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorUI?.updateWidget(this.monitorHDDElement); + await this.updateServer({switchHDD: value}); + }, + }; + + this.settingsHDD = { + id: 'Crystools.WhichHdd', + name: 'Partition to show', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], + type: 'combo', + defaultValue: '/', + data: [], + // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? + options: (value: string): any => { + const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); + return this.settingsHDD.data.map((m: any) => ({ + value: m, + text: m, + selected: !value ? m === which : m === value, + })); + }, + // @ts-ignore + onChange: async(value: string): Promise => { + await this.updateServer({whichHDD: value}); + }, + }; + }; + + + createSettings = (): void => { + app.ui.settings.addSetting(this.settingsRate); + app.ui.settings.addSetting(this.monitorRAMElement); + app.ui.settings.addSetting(this.monitorCPUElement); + + void this.getHDDsFromServer().then((data: string[]): void => { + // @ts-ignore + this.settingsHDD.data = data; + app.ui.settings.addSetting(this.settingsHDD); + }); + app.ui.settings.addSetting(this.monitorHDDElement); + + void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { + let moreThanOneGPU = false; + if (gpus.length > 1) { + moreThanOneGPU = true; + } + + gpus?.forEach(({name, index}) => { + + this.createSettingsGPUTemp(name, index, moreThanOneGPU); + this.createSettingsGPUVRAM(name, index, moreThanOneGPU); + this.createSettingsGPUUsage(name, index, moreThanOneGPU); + + }); + }); + }; + + updateServer = async(data: TStatsSettings): Promise => { + const resp = await api.fetchApi('/crystools/monitor', { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + }; + + updateServerGPU = async(index: number, data: TGpuSettings): Promise => { + const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + }; + + getHDDsFromServer = async(): Promise => { + return this.getDataFromServer('HDD'); + }; + + getGPUsFromServer = async(): Promise => { + return this.getDataFromServer('GPU'); + }; + + getDataFromServer = async (what: string): Promise => { + const resp = await api.fetchApi(`/crystools/monitor/${what}`, { + method: 'GET', + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.json(); + } + throw new Error(resp.statusText); + }; + + setup(): void { + const currentRate = + parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); + + this.monitorUI = new MonitorUI( + this.monitorCPUElement, + this.monitorRAMElement, + this.monitorHDDElement, + this.monitorGPUSettings, + this.monitorVRAMSettings, + this.monitorTemperatureSettings, + currentRate, + ); + + this.registerListeners(); + } + + registerListeners = (): void => { + api.addEventListener('crystools.monitor', (event: CustomEvent) => { + if (event?.detail === undefined) { + return; + } + this.monitorUI.updateAllMonitors(event.detail); + }, false); + }; +} + +const crystoolsMonitor = new CrystoolsMonitor(); +app.registerExtension({ + name: crystoolsMonitor.idExtensionName, + setup: crystoolsMonitor.setup.bind(crystoolsMonitor), +}); diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts index e69de29..124ae33 100644 --- a/web/monitorUI.d.ts +++ b/web/monitorUI.d.ts @@ -0,0 +1,20 @@ +import { ProgressBarUIBase } from './progressBarUI.js'; +export declare class MonitorUI extends ProgressBarUIBase { + private monitorCPUElement; + private monitorRAMElement; + private monitorHDDElement; + private monitorGPUSettings; + private monitorVRAMSettings; + private monitorTemperatureSettings; + private currentRate; + constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number); + refreshDisplay: () => void; + createDOM: () => void; + updateAllWidget: () => void; + updateWidget: (monitorSettings: TMonitorSettings) => void; + updateAllMonitors: (data: TStatsData) => void; + updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; + updateAllAnimationDuration: (value: number) => void; + updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; + createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; +} diff --git a/web/monitorUI.js b/web/monitorUI.js index 3918c74..8816b70 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1 +1,241 @@ -"use strict"; +import { app } from './comfy/index.js'; +import { ProgressBarUIBase } from './progressBarUI.js'; +export class MonitorUI extends ProgressBarUIBase { + constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { + super(); + Object.defineProperty(this, "monitorCPUElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorCPUElement + }); + Object.defineProperty(this, "monitorRAMElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorRAMElement + }); + Object.defineProperty(this, "monitorHDDElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorHDDElement + }); + Object.defineProperty(this, "monitorGPUSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorGPUSettings + }); + Object.defineProperty(this, "monitorVRAMSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorVRAMSettings + }); + Object.defineProperty(this, "monitorTemperatureSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorTemperatureSettings + }); + Object.defineProperty(this, "currentRate", { + enumerable: true, + configurable: true, + writable: true, + value: currentRate + }); + Object.defineProperty(this, "refreshDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.updateAllWidget(); + } + }); + Object.defineProperty(this, "createDOM", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + this.monitorGPUSettings.forEach((_monitorSettings, index) => { + this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); + this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); + this.monitorTemperatureSettings[index] && + this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); + }); + this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + } + }); + Object.defineProperty(this, "updateAllWidget", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + } + }); + Object.defineProperty(this, "updateWidget", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + } + }); + Object.defineProperty(this, "updateAllMonitors", { + enumerable: true, + configurable: true, + writable: true, + value: (data) => { + this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + if (data.gpus === undefined || data.gpus.length === 0) { + console.warn('UpdateAllMonitors: no GPU data'); + return; + } + this.monitorGPUSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.gpu_utilization); + } + else { + } + }); + this.monitorVRAMSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.vram_used_percent); + } + else { + } + }); + this.monitorTemperatureSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.gpu_temperature); + if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { + monitorSettings.htmlMonitorSliderRef.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; + } + } + else { + } + }); + } + }); + Object.defineProperty(this, "updateMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, percent) => { + if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { + return; + } + monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; + monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; + } + }); + Object.defineProperty(this, "updateAllAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + this.updatedAnimationDuration(this.monitorCPUElement, value); + this.updatedAnimationDuration(this.monitorRAMElement, value); + this.updatedAnimationDuration(this.monitorHDDElement, value); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + } + }); + Object.defineProperty(this, "updatedAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, value) => { + const slider = monitorSettings.htmlMonitorSliderRef; + if (!slider) { + return; + } + slider.style.transition = `width ${value.toFixed(1)}s`; + } + }); + Object.defineProperty(this, "createMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + if (!monitorSettings) { + return document.createElement('div'); + } + const htmlMain = document.createElement('div'); + htmlMain.setAttribute('id', monitorSettings.id); + htmlMain.classList.add('crystools-monitor'); + monitorSettings.htmlMonitorRef = htmlMain; + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.classList.add('crystools-text'); + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.classList.add('crystools-content'); + htmlMain.append(htmlMonitorContent); + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.classList.add('crystools-slider'); + if (monitorSettings.cssColorFinal) { + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } + else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.classList.add('crystools-label'); + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + htmlMonitorLabel.innerHTML = '0%'; + return monitorSettings.htmlMonitorRef; + } + }); + this.createDOM(); + } +} diff --git a/web/monitorUI.ts b/web/monitorUI.ts index 49c54b1..5b40235 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -1,213 +1,213 @@ -// import { app } from './comfy/index.js'; -// import { ProgressBarUIBase } from './progressBarUI.js'; -// -// export class MonitorUI extends ProgressBarUIBase { -// constructor( -// private monitorCPUElement: TMonitorSettings, -// private monitorRAMElement: TMonitorSettings, -// private monitorHDDElement: TMonitorSettings, -// private monitorGPUSettings: TMonitorSettings[], -// private monitorVRAMSettings: TMonitorSettings[], -// private monitorTemperatureSettings: TMonitorSettings[], -// private currentRate: number -// ) { -// super(); -// this.createDOM(); -// } -// -// refreshDisplay = (): void => { -// // console.log('refreshDisplay'); -// this.updateAllWidget(); -// }; -// -// override createDOM = (): void => { -// this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); -// this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); -// -// // gpu0 > gpu1 > vram0 > vram1 -// // this.monitorGPUSettings.forEach((monitorSettings) => { -// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); -// // }); -// // this.monitorVRAMSettings.forEach((monitorSettings) => { -// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); -// // }); -// // this.monitorTemperatureSettings.forEach((monitorSettings) => { -// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); -// // }); -// -// // gpu0 > vram0 > gpu1 > vram1 -// this.monitorGPUSettings.forEach((_monitorSettings, index) => { -// this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); -// this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); -// this.monitorTemperatureSettings[index] && -// this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); -// }); -// -// this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); -// -// this.updateAllAnimationDuration(this.currentRate); -// this.updateAllWidget(); -// }; -// -// -// updateAllWidget = (): void => { -// this.updateWidget(this.monitorCPUElement); -// this.updateWidget(this.monitorRAMElement); -// this.updateWidget(this.monitorHDDElement); -// -// this.monitorGPUSettings.forEach((monitorSettings) => { -// monitorSettings && this.updateWidget(monitorSettings); -// }); -// this.monitorVRAMSettings.forEach((monitorSettings) => { -// monitorSettings && this.updateWidget(monitorSettings); -// }); -// this.monitorTemperatureSettings.forEach((monitorSettings) => { -// monitorSettings && this.updateWidget(monitorSettings); -// }); -// }; -// -// /** -// * for the settings menu -// * @param monitorSettings -// */ -// updateWidget = (monitorSettings: TMonitorSettings): void => { -// const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); -// if (monitorSettings.htmlMonitorRef) { -// monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; -// } -// }; -// -// updateAllMonitors = (data: TStatsData): void => { -// // console.log('updateAllMonitors', data); -// this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); -// this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); -// this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); -// -// if (data.gpus === undefined || data.gpus.length === 0) { -// console.warn('UpdateAllMonitors: no GPU data'); -// return; -// } -// -// this.monitorGPUSettings.forEach((monitorSettings, index) => { -// if (data.gpus[index]) { -// const gpu = data.gpus[index]; -// if (gpu === undefined) { -// // console.error('UpdateAllMonitors: no GPU data for index', index); -// return; -// } -// -// this.updateMonitor(monitorSettings, gpu.gpu_utilization); -// } else { -// // console.error('UpdateAllMonitors: no GPU data for index', index); -// } -// }); -// -// this.monitorVRAMSettings.forEach((monitorSettings, index) => { -// if (data.gpus[index]) { -// const gpu = data.gpus[index]; -// if (gpu === undefined) { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// return; -// } -// -// this.updateMonitor(monitorSettings, gpu.vram_used_percent); -// } else { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// } -// }); -// -// this.monitorTemperatureSettings.forEach((monitorSettings, index) => { -// if (data.gpus[index]) { -// const gpu = data.gpus[index]; -// if (gpu === undefined) { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// return; -// } -// -// this.updateMonitor(monitorSettings, gpu.gpu_temperature); -// if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ -// monitorSettings.htmlMonitorSliderRef.style.backgroundColor = -// `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; -// } -// } else { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// } -// }); -// }; -// -// updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { -// if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { -// return; -// } -// -// monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; -// monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; -// }; -// -// updateAllAnimationDuration = (value: number): void => { -// this.updatedAnimationDuration(this.monitorCPUElement, value); -// this.updatedAnimationDuration(this.monitorRAMElement, value); -// this.updatedAnimationDuration(this.monitorHDDElement, value); -// this.monitorGPUSettings.forEach((monitorSettings) => { -// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); -// }); -// this.monitorVRAMSettings.forEach((monitorSettings) => { -// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); -// }); -// this.monitorTemperatureSettings.forEach((monitorSettings) => { -// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); -// }); -// }; -// -// updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { -// const slider = monitorSettings.htmlMonitorSliderRef; -// if (!slider) { -// return; -// } -// -// slider.style.transition = `width ${value.toFixed(1)}s`; -// }; -// -// -// createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { -// if (!monitorSettings) { -// // just for typescript -// return document.createElement('div'); -// } -// const htmlMain = document.createElement('div'); -// htmlMain.setAttribute('id', monitorSettings.id); -// htmlMain.classList.add('crystools-monitor'); -// monitorSettings.htmlMonitorRef = htmlMain; -// -// if (monitorSettings.title) { -// htmlMain.title = monitorSettings.title; -// } -// -// const htmlMonitorText = document.createElement('div'); -// htmlMonitorText.classList.add('crystools-text'); -// htmlMonitorText.innerHTML = monitorSettings.label; -// htmlMain.append(htmlMonitorText); -// -// const htmlMonitorContent = document.createElement('div'); -// htmlMonitorContent.classList.add('crystools-content'); -// htmlMain.append(htmlMonitorContent); -// -// const htmlMonitorSlider = document.createElement('div'); -// htmlMonitorSlider.classList.add('crystools-slider'); -// if(monitorSettings.cssColorFinal){ -// htmlMonitorSlider.style.backgroundColor = -// `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; -// } else { -// htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; -// } -// monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; -// htmlMonitorContent.append(htmlMonitorSlider); -// -// const htmlMonitorLabel = document.createElement('div'); -// htmlMonitorLabel.classList.add('crystools-label'); -// monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; -// htmlMonitorContent.append(htmlMonitorLabel); -// htmlMonitorLabel.innerHTML = '0%'; -// return monitorSettings.htmlMonitorRef; -// }; -// } +import { app } from './comfy/index.js'; +import { ProgressBarUIBase } from './progressBarUI.js'; + +export class MonitorUI extends ProgressBarUIBase { + constructor( + private monitorCPUElement: TMonitorSettings, + private monitorRAMElement: TMonitorSettings, + private monitorHDDElement: TMonitorSettings, + private monitorGPUSettings: TMonitorSettings[], + private monitorVRAMSettings: TMonitorSettings[], + private monitorTemperatureSettings: TMonitorSettings[], + private currentRate: number + ) { + super(); + this.createDOM(); + } + + refreshDisplay = (): void => { + // console.log('refreshDisplay'); + this.updateAllWidget(); + }; + + override createDOM = (): void => { + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + + // gpu0 > gpu1 > vram0 > vram1 + // this.monitorGPUSettings.forEach((monitorSettings) => { + // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); + // }); + // this.monitorVRAMSettings.forEach((monitorSettings) => { + // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); + // }); + // this.monitorTemperatureSettings.forEach((monitorSettings) => { + // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); + // }); + + // gpu0 > vram0 > gpu1 > vram1 + this.monitorGPUSettings.forEach((_monitorSettings, index) => { + this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); + this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); + this.monitorTemperatureSettings[index] && + this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); + }); + + this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + }; + + + updateAllWidget = (): void => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + }; + + /** + * for the settings menu + * @param monitorSettings + */ + updateWidget = (monitorSettings: TMonitorSettings): void => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + }; + + updateAllMonitors = (data: TStatsData): void => { + // console.log('updateAllMonitors', data); + this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + + if (data.gpus === undefined || data.gpus.length === 0) { + console.warn('UpdateAllMonitors: no GPU data'); + return; + } + + this.monitorGPUSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.gpu_utilization); + } else { + // console.error('UpdateAllMonitors: no GPU data for index', index); + } + }); + + this.monitorVRAMSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.vram_used_percent); + } else { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + } + }); + + this.monitorTemperatureSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.gpu_temperature); + if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ + monitorSettings.htmlMonitorSliderRef.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; + } + } else { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + } + }); + }; + + updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { + if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { + return; + } + + monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; + monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; + }; + + updateAllAnimationDuration = (value: number): void => { + this.updatedAnimationDuration(this.monitorCPUElement, value); + this.updatedAnimationDuration(this.monitorRAMElement, value); + this.updatedAnimationDuration(this.monitorHDDElement, value); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + }; + + updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { + const slider = monitorSettings.htmlMonitorSliderRef; + if (!slider) { + return; + } + + slider.style.transition = `width ${value.toFixed(1)}s`; + }; + + + createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { + if (!monitorSettings) { + // just for typescript + return document.createElement('div'); + } + const htmlMain = document.createElement('div'); + htmlMain.setAttribute('id', monitorSettings.id); + htmlMain.classList.add('crystools-monitor'); + monitorSettings.htmlMonitorRef = htmlMain; + + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.classList.add('crystools-text'); + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.classList.add('crystools-content'); + htmlMain.append(htmlMonitorContent); + + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.classList.add('crystools-slider'); + if(monitorSettings.cssColorFinal){ + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.classList.add('crystools-label'); + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + htmlMonitorLabel.innerHTML = '0%'; + return monitorSettings.htmlMonitorRef; + }; +} diff --git a/web/progressBar.js b/web/progressBar.js index 07ac324..d064aa6 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -102,7 +102,6 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: (value) => { - console.log('showProgressBar', value, this.newMenu); if (this.newMenu === NewMenuOptions.Disabled) { const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); if (container) { @@ -116,7 +115,6 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: () => { - console.log('updateDisplay'); const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; @@ -125,7 +123,6 @@ class CrystoolsProgressBar { this.setup(); break; default: - console.log('new menu', this.newMenu); } } if (this.newMenu === NewMenuOptions.Disabled) { diff --git a/web/progressBar.ts b/web/progressBar.ts index 797c280..8dbaef9 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -41,7 +41,6 @@ class CrystoolsProgressBar { }; showProgressBar = (value: boolean): void => { - console.log('showProgressBar', value, this.newMenu); if (this.newMenu === NewMenuOptions.Disabled) { const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); @@ -54,7 +53,6 @@ class CrystoolsProgressBar { }; updateDisplay = (): void => { - console.log('updateDisplay'); const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { @@ -65,7 +63,7 @@ class CrystoolsProgressBar { this.setup(); break; default: - console.log('new menu', this.newMenu); + // console.log('new menu', this.newMenu); } } diff --git a/web/progressBarUI.js b/web/progressBarUI.js index e78f32e..b9c8562 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -38,7 +38,6 @@ export class ProgressBarUIBase { value: NewMenuOptions.Disabled }); this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - console.log('menu', this.newMenu); if (this.newMenu === NewMenuOptions.Disabled) { this.createRoot(); } @@ -106,7 +105,6 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: () => { - console.log('create'); const htmlContainer = document.createElement('div'); htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index ad92368..fdcf220 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -20,11 +20,9 @@ export abstract class ProgressBarUIBase { protected constructor() { this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - console.log('menu', this.newMenu); if(this.newMenu === NewMenuOptions.Disabled) { this.createRoot(); } - // window.addEventListener('resize', () => this.refreshDisplay()); } createRoot(): void { @@ -66,7 +64,6 @@ export class ProgressBarUI extends ProgressBarUIBase{ } createDOM = (): void => { - console.log('create'); const htmlContainer = document.createElement('div'); htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); diff --git a/web/types.d.ts b/web/types.d.ts index e1eee71..690086d 100644 --- a/web/types.d.ts +++ b/web/types.d.ts @@ -48,9 +48,10 @@ type TMonitorSettings = { symbol: string, // on monitor title?: string, // on monitor tooltip?: string, // on settings - type: 'boolean' | 'number' | 'string', - defaultValue: boolean, - onChange: (value: boolean) => Promise, + type: 'boolean' | 'number' | 'string' | 'slider' | 'combo', + defaultValue: boolean | number | string, + data?: any, + onChange: (value: boolean | number | string) => Promise, htmlMonitorRef?: HTMLDivElement, htmlMonitorSliderRef?: HTMLDivElement, htmlMonitorLabelRef?: HTMLDivElement, From 91fee20c5f481e4d6984c632ac8809015d764e51 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sun, 22 Sep 2024 01:25:57 +0200 Subject: [PATCH 15/31] starting with horizontal... finally3 --- web/monitor.js | 30 ++++++++++++++++++++++++++++++ web/monitor.ts | 25 +++++++++++++++++++++++-- web/progressBar.js | 21 +++++++++------------ web/progressBar.ts | 22 +++++++++------------- web/progressBarUI.js | 5 ----- web/progressBarUI.ts | 4 ---- 6 files changed, 71 insertions(+), 36 deletions(-) diff --git a/web/monitor.js b/web/monitor.js index c27a23b..08cf2cc 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -3,6 +3,7 @@ import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; import { Colors } from './styles.js'; import { convertNumberToPascalCase } from './utils.js'; +import { NewMenuOptions } from './progressBarUI.js'; class CrystoolsMonitor { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -23,6 +24,12 @@ class CrystoolsMonitor { writable: true, value: void 0 }); + Object.defineProperty(this, "newMenu", { + enumerable: true, + configurable: true, + writable: true, + value: NewMenuOptions.Disabled + }); Object.defineProperty(this, "settingsRate", { enumerable: true, configurable: true, @@ -350,6 +357,21 @@ class CrystoolsMonitor { }); } }); + Object.defineProperty(this, "updateDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + console.log('updateDisplay'); + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + if (this.newMenu === NewMenuOptions.Disabled) { + this.setup(); + } + } + } + }); Object.defineProperty(this, "updateServer", { enumerable: true, configurable: true, @@ -426,13 +448,21 @@ class CrystoolsMonitor { }, false); } }); + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + window.addEventListener('resize', () => this.updateDisplay()); this.createSettingsRate(); this.createSettingsCPU(); this.createSettingsRAM(); this.createSettingsHDD(); this.createSettings(); + this.updateDisplay(); } setup() { + console.log('setup'); + if (this.monitorUI) { + return; + } + console.log('setup nuevo'); const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate); this.registerListeners(); diff --git a/web/monitor.ts b/web/monitor.ts index ce141e1..1b79875 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -3,12 +3,14 @@ import { commonPrefix } from './common.js'; import { MonitorUI } from './monitorUI.js'; import { Colors } from './styles.js'; import { convertNumberToPascalCase } from './utils.js'; +import { NewMenuOptions } from './progressBarUI.js'; class CrystoolsMonitor { idExtensionName = 'Crystools.monitor'; menuPrefix = commonPrefix; monitorUI: MonitorUI; + newMenu: NewMenuOptions = NewMenuOptions.Disabled; settingsRate: TMonitorSettings; monitorCPUElement: TMonitorSettings; @@ -19,13 +21,15 @@ class CrystoolsMonitor { monitorVRAMSettings: TMonitorSettings[] = []; monitorTemperatureSettings: TMonitorSettings[] = []; - constructor() { + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + window.addEventListener('resize', () => this.updateDisplay()); this.createSettingsRate(); this.createSettingsCPU(); this.createSettingsRAM(); this.createSettingsHDD(); this.createSettings(); + this.updateDisplay(); } createSettingsRate = (): void => { @@ -280,7 +284,6 @@ class CrystoolsMonitor { }; }; - createSettings = (): void => { app.ui.settings.addSetting(this.settingsRate); app.ui.settings.addSetting(this.monitorRAMElement); @@ -309,6 +312,19 @@ class CrystoolsMonitor { }); }; + updateDisplay = (): void => { + console.log('updateDisplay'); + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + + if (this.newMenu === NewMenuOptions.Disabled) { + this.setup(); + } + } + }; + updateServer = async(data: TStatsSettings): Promise => { const resp = await api.fetchApi('/crystools/monitor', { method: 'PATCH', @@ -353,6 +369,11 @@ class CrystoolsMonitor { }; setup(): void { + console.log('setup'); + if (this.monitorUI) { + return; + } + console.log('setup nuevo'); const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); diff --git a/web/progressBar.js b/web/progressBar.js index d064aa6..d73f560 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -75,7 +75,7 @@ class CrystoolsProgressBar { writable: true, value: undefined }); - Object.defineProperty(this, "progressBarVertical", { + Object.defineProperty(this, "progressBarUI", { enumerable: true, configurable: true, writable: true, @@ -118,15 +118,12 @@ class CrystoolsProgressBar { const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; - switch (this.newMenu) { - case NewMenuOptions.Disabled: - this.setup(); - break; - default: + if (this.newMenu === NewMenuOptions.Disabled) { + this.setup(); } } if (this.newMenu === NewMenuOptions.Disabled) { - this.progressBarVertical?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + this.progressBarUI?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } } }); @@ -186,21 +183,21 @@ class CrystoolsProgressBar { } }); this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + window.addEventListener('resize', () => this.updateDisplay()); this.createSettings(); this.updateDisplay(); - window.addEventListener('resize', () => this.updateDisplay()); } setup() { - if (this.progressBarVertical) { + if (this.progressBarUI) { this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); return; } if (this.newMenu !== NewMenuOptions.Disabled) { return; } - this.progressBarVertical = new ProgressBarUI(this.htmlIdCrystoolsProgressBarContainer, this.centerNode); - this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; - this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; + this.progressBarUI = new ProgressBarUI(this.htmlIdCrystoolsProgressBarContainer, this.centerNode); + this.htmlProgressSliderRef = this.progressBarUI.htmlProgressSliderRef; + this.htmlProgressLabelRef = this.progressBarUI.htmlProgressLabelRef; this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); this.registerListeners(); } diff --git a/web/progressBar.ts b/web/progressBar.ts index 8dbaef9..914ee5e 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -18,13 +18,13 @@ class CrystoolsProgressBar { htmlProgressSliderRef?: HTMLDivElement = undefined; htmlProgressLabelRef?: HTMLDivElement = undefined; - progressBarVertical: ProgressBarUI; + progressBarUI: ProgressBarUI; constructor() { this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + window.addEventListener('resize', () => this.updateDisplay()); this.createSettings(); this.updateDisplay(); - window.addEventListener('resize', () => this.updateDisplay()); } // not on setup because this affect the order on settings, I prefer to options at first @@ -58,23 +58,19 @@ class CrystoolsProgressBar { if (newMenu !== this.newMenu) { this.newMenu = newMenu; - switch (this.newMenu) { - case NewMenuOptions.Disabled: - this.setup(); - break; - default: - // console.log('new menu', this.newMenu); + if (this.newMenu === NewMenuOptions.Disabled) { + this.setup(); } } if (this.newMenu === NewMenuOptions.Disabled) { - this.progressBarVertical?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + this.progressBarUI?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } }; setup(): void { - if (this.progressBarVertical) { + if (this.progressBarUI) { this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); return; } @@ -82,12 +78,12 @@ class CrystoolsProgressBar { return; } - this.progressBarVertical = new ProgressBarUI( + this.progressBarUI = new ProgressBarUI( this.htmlIdCrystoolsProgressBarContainer, this.centerNode); - this.htmlProgressSliderRef = this.progressBarVertical.htmlProgressSliderRef; - this.htmlProgressLabelRef = this.progressBarVertical.htmlProgressLabelRef; + this.htmlProgressSliderRef = this.progressBarUI.htmlProgressSliderRef; + this.htmlProgressLabelRef = this.progressBarUI.htmlProgressLabelRef; this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); this.registerListeners(); diff --git a/web/progressBarUI.js b/web/progressBarUI.js index b9c8562..7010de0 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -130,13 +130,9 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: () => { - console.log('dddd', this.newMenu); if (this.newMenu === NewMenuOptions.Disabled) { this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } - else { - console.log('refresh'); - } } }); Object.defineProperty(this, "updateDisplay", { @@ -144,7 +140,6 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: (currentStatus, timeStart, currentProgress) => { - console.log('entra'); if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); return; diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index fdcf220..fb9b9b2 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -88,16 +88,12 @@ export class ProgressBarUI extends ProgressBarUIBase{ }; refreshDisplay = (): void => { - console.log('dddd', this.newMenu); if(this.newMenu === NewMenuOptions.Disabled) { this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); - } else { - console.log('refresh'); } }; updateDisplay = (currentStatus: EStatus, timeStart: number, currentProgress: number): void => { - console.log('entra'); if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); return; From b05bcd74a0f1cca670e9526fd124590617e9e0d9 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sun, 22 Sep 2024 13:52:08 +0200 Subject: [PATCH 16/31] progress bar optimize --- web/monitor.css | 2 +- web/monitor.d.ts | 1 - web/monitor.js | 476 +-------------------- web/monitor.ts | 818 +++++++++++++++++++------------------ web/monitorUI.d.ts | 20 - web/monitorUI.js | 242 +---------- web/monitorUI.ts | 453 ++++++++++---------- web/progressBar.js | 62 +-- web/progressBar.ts | 50 +-- web/progressBarUI.d.ts | 25 +- web/progressBarUI.js | 97 +---- web/progressBarUI.ts | 76 +--- web/progressBarUIBase.d.ts | 22 + web/progressBarUIBase.js | 73 ++++ web/progressBarUIBase.ts | 50 +++ 15 files changed, 866 insertions(+), 1601 deletions(-) create mode 100644 web/progressBarUIBase.d.ts create mode 100644 web/progressBarUIBase.js create mode 100644 web/progressBarUIBase.ts diff --git a/web/monitor.css b/web/monitor.css index 1903295..ad4b620 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -1,4 +1,4 @@ -#crystools-root { +#crystools-root-old { /*background-color: red;*/ display: flex; width: 100%; diff --git a/web/monitor.d.ts b/web/monitor.d.ts index cb0ff5c..e69de29 100644 --- a/web/monitor.d.ts +++ b/web/monitor.d.ts @@ -1 +0,0 @@ -export {}; diff --git a/web/monitor.js b/web/monitor.js index 08cf2cc..3918c74 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1,475 +1 @@ -import { app, api } from './comfy/index.js'; -import { commonPrefix } from './common.js'; -import { MonitorUI } from './monitorUI.js'; -import { Colors } from './styles.js'; -import { convertNumberToPascalCase } from './utils.js'; -import { NewMenuOptions } from './progressBarUI.js'; -class CrystoolsMonitor { - constructor() { - Object.defineProperty(this, "idExtensionName", { - enumerable: true, - configurable: true, - writable: true, - value: 'Crystools.monitor' - }); - Object.defineProperty(this, "menuPrefix", { - enumerable: true, - configurable: true, - writable: true, - value: commonPrefix - }); - Object.defineProperty(this, "monitorUI", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "newMenu", { - enumerable: true, - configurable: true, - writable: true, - value: NewMenuOptions.Disabled - }); - Object.defineProperty(this, "settingsRate", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "monitorCPUElement", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "monitorRAMElement", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "monitorHDDElement", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "settingsHDD", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "monitorGPUSettings", { - enumerable: true, - configurable: true, - writable: true, - value: [] - }); - Object.defineProperty(this, "monitorVRAMSettings", { - enumerable: true, - configurable: true, - writable: true, - value: [] - }); - Object.defineProperty(this, "monitorTemperatureSettings", { - enumerable: true, - configurable: true, - writable: true, - value: [] - }); - Object.defineProperty(this, "createSettingsRate", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.settingsRate = { - id: 'Crystools.RefreshRate', - name: 'Refresh per second', - category: ['Crystools', this.menuPrefix + ' Refresh Rate'], - tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', - type: 'slider', - attrs: { - min: 0, - max: 2, - step: 0.25, - }, - defaultValue: .5, - onChange: async (value) => { - let valueNumber; - try { - valueNumber = parseFloat(value); - if (isNaN(valueNumber)) { - throw new Error('invalid value'); - } - } - catch (error) { - console.error(error); - return; - } - try { - await this.updateServer({ rate: valueNumber }); - } - catch (error) { - console.error(error); - return; - } - if (valueNumber === 0) { - this.monitorUI.updateAllMonitors({ - cpu_utilization: 0, - device: 'cpu', - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); - } - this.monitorUI?.updateAllAnimationDuration(valueNumber); - }, - }; - } - }); - Object.defineProperty(this, "createSettingsCPU", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.monitorCPUElement = { - id: 'Crystools.ShowCpu', - name: 'CPU Usage', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], - type: 'boolean', - label: 'CPU', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.CPU, - onChange: async (value) => { - this.monitorUI?.updateWidget(this.monitorCPUElement); - await this.updateServer({ switchCPU: value }); - }, - }; - } - }); - Object.defineProperty(this, "createSettingsRAM", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.monitorRAMElement = { - id: 'Crystools.ShowRam', - name: 'RAM Used', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], - type: 'boolean', - label: 'RAM', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.RAM, - onChange: async (value) => { - this.monitorUI?.updateWidget(this.monitorRAMElement); - await this.updateServer({ switchRAM: value }); - }, - }; - } - }); - Object.defineProperty(this, "createSettingsGPUUsage", { - enumerable: true, - configurable: true, - writable: true, - value: (name, index, moreThanOneGPU) => { - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - let label = 'GPU '; - label += moreThanOneGPU ? index : ''; - const monitorGPUNElement = { - id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), - name: ' Usage', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], - type: 'boolean', - label, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.GPU, - onChange: async (value) => { - this.monitorUI?.updateWidget(monitorGPUNElement); - void await this.updateServerGPU(index, { utilization: value }); - }, - }; - this.monitorGPUSettings[index] = monitorGPUNElement; - app.ui.settings.addSetting(this.monitorGPUSettings[index]); - } - }); - Object.defineProperty(this, "createSettingsGPUVRAM", { - enumerable: true, - configurable: true, - writable: true, - value: (name, index, moreThanOneGPU) => { - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - let label = 'VRAM'; - label += moreThanOneGPU ? index : ''; - const monitorVRAMNElement = { - id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), - name: 'VRAM', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], - type: 'boolean', - label: label, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.VRAM, - onChange: async (value) => { - this.monitorUI?.updateWidget(monitorVRAMNElement); - void await this.updateServerGPU(index, { vram: value }); - }, - }; - this.monitorVRAMSettings[index] = monitorVRAMNElement; - app.ui.settings.addSetting(this.monitorVRAMSettings[index]); - } - }); - Object.defineProperty(this, "createSettingsGPUTemp", { - enumerable: true, - configurable: true, - writable: true, - value: (name, index, moreThanOneGPU) => { - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - let label = 'Temp '; - label += moreThanOneGPU ? index : ''; - const monitorTemperatureNElement = { - id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), - name: 'Temperature', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], - type: 'boolean', - label: label, - symbol: '°', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.TEMP_START, - cssColorFinal: Colors.TEMP_END, - onChange: async (value) => { - this.monitorUI?.updateWidget(monitorTemperatureNElement); - void await this.updateServerGPU(index, { temperature: value }); - }, - }; - this.monitorTemperatureSettings[index] = monitorTemperatureNElement; - app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); - } - }); - Object.defineProperty(this, "createSettingsHDD", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.monitorHDDElement = { - id: 'Crystools.ShowHdd', - name: 'Show HDD Used', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], - type: 'boolean', - label: 'HDD', - symbol: '%', - defaultValue: false, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.DISK, - onChange: async (value) => { - this.monitorUI?.updateWidget(this.monitorHDDElement); - await this.updateServer({ switchHDD: value }); - }, - }; - this.settingsHDD = { - id: 'Crystools.WhichHdd', - name: 'Partition to show', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], - type: 'combo', - defaultValue: '/', - data: [], - options: (value) => { - const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); - return this.settingsHDD.data.map((m) => ({ - value: m, - text: m, - selected: !value ? m === which : m === value, - })); - }, - onChange: async (value) => { - await this.updateServer({ whichHDD: value }); - }, - }; - } - }); - Object.defineProperty(this, "createSettings", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - app.ui.settings.addSetting(this.settingsRate); - app.ui.settings.addSetting(this.monitorRAMElement); - app.ui.settings.addSetting(this.monitorCPUElement); - void this.getHDDsFromServer().then((data) => { - this.settingsHDD.data = data; - app.ui.settings.addSetting(this.settingsHDD); - }); - app.ui.settings.addSetting(this.monitorHDDElement); - void this.getGPUsFromServer().then((gpus) => { - let moreThanOneGPU = false; - if (gpus.length > 1) { - moreThanOneGPU = true; - } - gpus?.forEach(({ name, index }) => { - this.createSettingsGPUTemp(name, index, moreThanOneGPU); - this.createSettingsGPUVRAM(name, index, moreThanOneGPU); - this.createSettingsGPUUsage(name, index, moreThanOneGPU); - }); - }); - } - }); - Object.defineProperty(this, "updateDisplay", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - console.log('updateDisplay'); - const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - if (newMenu !== this.newMenu) { - this.newMenu = newMenu; - if (this.newMenu === NewMenuOptions.Disabled) { - this.setup(); - } - } - } - }); - Object.defineProperty(this, "updateServer", { - enumerable: true, - configurable: true, - writable: true, - value: async (data) => { - const resp = await api.fetchApi('/crystools/monitor', { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - } - }); - Object.defineProperty(this, "updateServerGPU", { - enumerable: true, - configurable: true, - writable: true, - value: async (index, data) => { - const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - } - }); - Object.defineProperty(this, "getHDDsFromServer", { - enumerable: true, - configurable: true, - writable: true, - value: async () => { - return this.getDataFromServer('HDD'); - } - }); - Object.defineProperty(this, "getGPUsFromServer", { - enumerable: true, - configurable: true, - writable: true, - value: async () => { - return this.getDataFromServer('GPU'); - } - }); - Object.defineProperty(this, "getDataFromServer", { - enumerable: true, - configurable: true, - writable: true, - value: async (what) => { - const resp = await api.fetchApi(`/crystools/monitor/${what}`, { - method: 'GET', - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.json(); - } - throw new Error(resp.statusText); - } - }); - Object.defineProperty(this, "registerListeners", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - api.addEventListener('crystools.monitor', (event) => { - if (event?.detail === undefined) { - return; - } - this.monitorUI.updateAllMonitors(event.detail); - }, false); - } - }); - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - window.addEventListener('resize', () => this.updateDisplay()); - this.createSettingsRate(); - this.createSettingsCPU(); - this.createSettingsRAM(); - this.createSettingsHDD(); - this.createSettings(); - this.updateDisplay(); - } - setup() { - console.log('setup'); - if (this.monitorUI) { - return; - } - console.log('setup nuevo'); - const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); - this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate); - this.registerListeners(); - } -} -const crystoolsMonitor = new CrystoolsMonitor(); -app.registerExtension({ - name: crystoolsMonitor.idExtensionName, - setup: crystoolsMonitor.setup.bind(crystoolsMonitor), -}); +"use strict"; diff --git a/web/monitor.ts b/web/monitor.ts index 1b79875..b2766d2 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,407 +1,411 @@ -import { app, api } from './comfy/index.js'; -import { commonPrefix } from './common.js'; -import { MonitorUI } from './monitorUI.js'; -import { Colors } from './styles.js'; -import { convertNumberToPascalCase } from './utils.js'; -import { NewMenuOptions } from './progressBarUI.js'; - -class CrystoolsMonitor { - idExtensionName = 'Crystools.monitor'; - menuPrefix = commonPrefix; - - monitorUI: MonitorUI; - newMenu: NewMenuOptions = NewMenuOptions.Disabled; - - settingsRate: TMonitorSettings; - monitorCPUElement: TMonitorSettings; - monitorRAMElement: TMonitorSettings; - monitorHDDElement: TMonitorSettings; - settingsHDD: TMonitorSettings; - monitorGPUSettings: TMonitorSettings[] = []; - monitorVRAMSettings: TMonitorSettings[] = []; - monitorTemperatureSettings: TMonitorSettings[] = []; - - constructor() { - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - window.addEventListener('resize', () => this.updateDisplay()); - this.createSettingsRate(); - this.createSettingsCPU(); - this.createSettingsRAM(); - this.createSettingsHDD(); - this.createSettings(); - this.updateDisplay(); - } - - createSettingsRate = (): void => { - this.settingsRate = { - id: 'Crystools.RefreshRate', - name: 'Refresh per second', - category: ['Crystools', this.menuPrefix + ' Refresh Rate'], - tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', - type: 'slider', - attrs: { - min: 0, - max: 2, - step: 0.25, - }, - defaultValue: .5, - // @ts-ignore - onChange: async(value: string): Promise => { - let valueNumber: number; - - try { - valueNumber = parseFloat(value); - if (isNaN(valueNumber)) { - throw new Error('invalid value'); - } - } catch (error) { - console.error(error); - return; - } - try { - await this.updateServer({rate: valueNumber}); - } catch (error) { - console.error(error); - return; - } - - if (valueNumber === 0) { - this.monitorUI.updateAllMonitors({ - cpu_utilization: 0, - device: 'cpu', - - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); - } - - this.monitorUI?.updateAllAnimationDuration(valueNumber); - }, - }; - }; - - createSettingsCPU = (): void => { - // CPU Variables - this.monitorCPUElement = { - id: 'Crystools.ShowCpu', - name: 'CPU Usage', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], - type: 'boolean', - label: 'CPU', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.CPU, - // @ts-ignore - onChange: async(value: boolean): Promise => { - this.monitorUI?.updateWidget(this.monitorCPUElement); - await this.updateServer({switchCPU: value}); - }, - }; - }; - - createSettingsRAM = (): void => { - // RAM Variables - this.monitorRAMElement = { - id: 'Crystools.ShowRam', - name: 'RAM Used', - category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], - type: 'boolean', - label: 'RAM', - symbol: '%', - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.RAM, - // @ts-ignore - onChange: async(value: boolean): Promise => { - this.monitorUI?.updateWidget(this.monitorRAMElement); - await this.updateServer({switchRAM: value}); - }, - }; - }; - - createSettingsGPUUsage = (name: string, index: number, moreThanOneGPU: boolean): void => { - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - - let label = 'GPU '; - label += moreThanOneGPU ? index : ''; - - const monitorGPUNElement: TMonitorSettings = { - id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), - name: ' Usage', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], - type: 'boolean', - label, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.GPU, - // @ts-ignore - onChange: async(value: boolean): Promise => { - this.monitorUI?.updateWidget(monitorGPUNElement); - void await this.updateServerGPU(index, {utilization: value}); - }, - }; - - this.monitorGPUSettings[index] = monitorGPUNElement; - app.ui.settings.addSetting(this.monitorGPUSettings[index]); - }; - - createSettingsGPUVRAM = (name: string, index: number, moreThanOneGPU: boolean): void => { - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - - let label = 'VRAM'; - label += moreThanOneGPU ? index : ''; - - // GPU VRAM Variables - const monitorVRAMNElement: TMonitorSettings = { - id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), - name: 'VRAM', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], - type: 'boolean', - label: label, - symbol: '%', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.VRAM, - // @ts-ignore - onChange: async(value: boolean): Promise => { - this.monitorUI?.updateWidget(monitorVRAMNElement); - void await this.updateServerGPU(index, {vram: value}); - }, - }; - - this.monitorVRAMSettings[index] = monitorVRAMNElement; - app.ui.settings.addSetting(this.monitorVRAMSettings[index]); - }; - - createSettingsGPUTemp = (name: string, index: number, moreThanOneGPU: boolean): void => { - if (name === undefined || index === undefined) { - console.warn('getGPUsFromServer: name or index undefined', name, index); - return; - } - - let label = 'Temp '; - label += moreThanOneGPU ? index : ''; - - // GPU Temperature Variables - const monitorTemperatureNElement: TMonitorSettings = { - id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), - name: 'Temperature', - category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], - type: 'boolean', - label: label, - symbol: '°', - title: `${index}: ${name}`, - defaultValue: true, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.TEMP_START, - cssColorFinal: Colors.TEMP_END, - // @ts-ignore - onChange: async(value: boolean): Promise => { - this.monitorUI?.updateWidget(monitorTemperatureNElement); - void await this.updateServerGPU(index, {temperature: value}); - }, - }; - - this.monitorTemperatureSettings[index] = monitorTemperatureNElement; - app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); - }; - - createSettingsHDD = (): void => { - // HDD Variables - this.monitorHDDElement = { - id: 'Crystools.ShowHdd', - name: 'Show HDD Used', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], - type: 'boolean', - label: 'HDD', - symbol: '%', - // tooltip: 'See Partition to show (HDD)', - defaultValue: false, - htmlMonitorRef: undefined, - htmlMonitorSliderRef: undefined, - htmlMonitorLabelRef: undefined, - cssColor: Colors.DISK, - // @ts-ignore - onChange: async(value: boolean): Promise => { - this.monitorUI?.updateWidget(this.monitorHDDElement); - await this.updateServer({switchHDD: value}); - }, - }; - - this.settingsHDD = { - id: 'Crystools.WhichHdd', - name: 'Partition to show', - category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], - type: 'combo', - defaultValue: '/', - data: [], - // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? - options: (value: string): any => { - const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); - return this.settingsHDD.data.map((m: any) => ({ - value: m, - text: m, - selected: !value ? m === which : m === value, - })); - }, - // @ts-ignore - onChange: async(value: string): Promise => { - await this.updateServer({whichHDD: value}); - }, - }; - }; - - createSettings = (): void => { - app.ui.settings.addSetting(this.settingsRate); - app.ui.settings.addSetting(this.monitorRAMElement); - app.ui.settings.addSetting(this.monitorCPUElement); - - void this.getHDDsFromServer().then((data: string[]): void => { - // @ts-ignore - this.settingsHDD.data = data; - app.ui.settings.addSetting(this.settingsHDD); - }); - app.ui.settings.addSetting(this.monitorHDDElement); - - void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { - let moreThanOneGPU = false; - if (gpus.length > 1) { - moreThanOneGPU = true; - } - - gpus?.forEach(({name, index}) => { - - this.createSettingsGPUTemp(name, index, moreThanOneGPU); - this.createSettingsGPUVRAM(name, index, moreThanOneGPU); - this.createSettingsGPUUsage(name, index, moreThanOneGPU); - - }); - }); - }; - - updateDisplay = (): void => { - console.log('updateDisplay'); - const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - - if (newMenu !== this.newMenu) { - this.newMenu = newMenu; - - if (this.newMenu === NewMenuOptions.Disabled) { - this.setup(); - } - } - }; - - updateServer = async(data: TStatsSettings): Promise => { - const resp = await api.fetchApi('/crystools/monitor', { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - }; - - updateServerGPU = async(index: number, data: TGpuSettings): Promise => { - const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { - method: 'PATCH', - body: JSON.stringify(data), - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.text(); - } - throw new Error(resp.statusText); - }; - - getHDDsFromServer = async(): Promise => { - return this.getDataFromServer('HDD'); - }; - - getGPUsFromServer = async(): Promise => { - return this.getDataFromServer('GPU'); - }; - - getDataFromServer = async (what: string): Promise => { - const resp = await api.fetchApi(`/crystools/monitor/${what}`, { - method: 'GET', - cache: 'no-store', - }); - if (resp.status === 200) { - return await resp.json(); - } - throw new Error(resp.statusText); - }; - - setup(): void { - console.log('setup'); - if (this.monitorUI) { - return; - } - console.log('setup nuevo'); - const currentRate = - parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); - - this.monitorUI = new MonitorUI( - this.monitorCPUElement, - this.monitorRAMElement, - this.monitorHDDElement, - this.monitorGPUSettings, - this.monitorVRAMSettings, - this.monitorTemperatureSettings, - currentRate, - ); - - this.registerListeners(); - } - - registerListeners = (): void => { - api.addEventListener('crystools.monitor', (event: CustomEvent) => { - if (event?.detail === undefined) { - return; - } - this.monitorUI.updateAllMonitors(event.detail); - }, false); - }; -} - -const crystoolsMonitor = new CrystoolsMonitor(); -app.registerExtension({ - name: crystoolsMonitor.idExtensionName, - setup: crystoolsMonitor.setup.bind(crystoolsMonitor), -}); +// import { app, api } from './comfy/index.js'; +// import { commonPrefix } from './common.js'; +// import { MonitorUI } from './monitorUI.js'; +// import { Colors } from './styles.js'; +// import { convertNumberToPascalCase } from './utils.js'; +// import { NewMenuOptions } from './progressBarUIBase.js'; +// +// class CrystoolsMonitor { +// idExtensionName = 'Crystools.monitor'; +// menuPrefix = commonPrefix; +// +// monitorUI: MonitorUI; +// newMenu: NewMenuOptions = NewMenuOptions.Disabled; +// +// settingsRate: TMonitorSettings; +// monitorCPUElement: TMonitorSettings; +// monitorRAMElement: TMonitorSettings; +// monitorHDDElement: TMonitorSettings; +// settingsHDD: TMonitorSettings; +// monitorGPUSettings: TMonitorSettings[] = []; +// monitorVRAMSettings: TMonitorSettings[] = []; +// monitorTemperatureSettings: TMonitorSettings[] = []; +// +// constructor() { +// this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); +// window.addEventListener('resize', () => this.updateDisplay()); +// this.createSettingsRate(); +// this.createSettingsCPU(); +// this.createSettingsRAM(); +// this.createSettingsHDD(); +// this.createSettings(); +// this.updateDisplay(); +// } +// +// createSettingsRate = (): void => { +// this.settingsRate = { +// id: 'Crystools.RefreshRate', +// name: 'Refresh per second', +// category: ['Crystools', this.menuPrefix + ' Refresh Rate'], +// tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', +// type: 'slider', +// attrs: { +// min: 0, +// max: 2, +// step: 0.25, +// }, +// defaultValue: .5, +// // @ts-ignore +// onChange: async(value: string): Promise => { +// let valueNumber: number; +// +// try { +// valueNumber = parseFloat(value); +// if (isNaN(valueNumber)) { +// throw new Error('invalid value'); +// } +// } catch (error) { +// console.error(error); +// return; +// } +// try { +// await this.updateServer({rate: valueNumber}); +// } catch (error) { +// console.error(error); +// return; +// } +// +// if (valueNumber === 0) { +// this.monitorUI.updateAllMonitors({ +// cpu_utilization: 0, +// device: 'cpu', +// +// gpus: [ +// { +// gpu_utilization: 0, +// gpu_temperature: 0, +// vram_total: 0, +// vram_used: 0, +// vram_used_percent: 0, +// }, +// ], +// hdd_total: 0, +// hdd_used: 0, +// hdd_used_percent: 0, +// ram_total: 0, +// ram_used: 0, +// ram_used_percent: 0, +// }); +// } +// +// this.monitorUI?.updateAllAnimationDuration(valueNumber); +// }, +// }; +// }; +// +// createSettingsCPU = (): void => { +// // CPU Variables +// this.monitorCPUElement = { +// id: 'Crystools.ShowCpu', +// name: 'CPU Usage', +// category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], +// type: 'boolean', +// label: 'CPU', +// symbol: '%', +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.CPU, +// // @ts-ignore +// onChange: async(value: boolean): Promise => { +// this.monitorUI?.updateWidget(this.monitorCPUElement); +// await this.updateServer({switchCPU: value}); +// }, +// }; +// }; +// +// createSettingsRAM = (): void => { +// // RAM Variables +// this.monitorRAMElement = { +// id: 'Crystools.ShowRam', +// name: 'RAM Used', +// category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], +// type: 'boolean', +// label: 'RAM', +// symbol: '%', +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.RAM, +// // @ts-ignore +// onChange: async(value: boolean): Promise => { +// this.monitorUI?.updateWidget(this.monitorRAMElement); +// await this.updateServer({switchRAM: value}); +// }, +// }; +// }; +// +// createSettingsGPUUsage = (name: string, index: number, moreThanOneGPU: boolean): void => { +// if (name === undefined || index === undefined) { +// console.warn('getGPUsFromServer: name or index undefined', name, index); +// return; +// } +// +// let label = 'GPU '; +// label += moreThanOneGPU ? index : ''; +// +// const monitorGPUNElement: TMonitorSettings = { +// id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), +// name: ' Usage', +// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], +// type: 'boolean', +// label, +// symbol: '%', +// title: `${index}: ${name}`, +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.GPU, +// // @ts-ignore +// onChange: async(value: boolean): Promise => { +// this.monitorUI?.updateWidget(monitorGPUNElement); +// void await this.updateServerGPU(index, {utilization: value}); +// }, +// }; +// +// this.monitorGPUSettings[index] = monitorGPUNElement; +// app.ui.settings.addSetting(this.monitorGPUSettings[index]); +// }; +// +// createSettingsGPUVRAM = (name: string, index: number, moreThanOneGPU: boolean): void => { +// if (name === undefined || index === undefined) { +// console.warn('getGPUsFromServer: name or index undefined', name, index); +// return; +// } +// +// let label = 'VRAM'; +// label += moreThanOneGPU ? index : ''; +// +// // GPU VRAM Variables +// const monitorVRAMNElement: TMonitorSettings = { +// id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), +// name: 'VRAM', +// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], +// type: 'boolean', +// label: label, +// symbol: '%', +// title: `${index}: ${name}`, +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.VRAM, +// // @ts-ignore +// onChange: async(value: boolean): Promise => { +// this.monitorUI?.updateWidget(monitorVRAMNElement); +// void await this.updateServerGPU(index, {vram: value}); +// }, +// }; +// +// this.monitorVRAMSettings[index] = monitorVRAMNElement; +// app.ui.settings.addSetting(this.monitorVRAMSettings[index]); +// }; +// +// createSettingsGPUTemp = (name: string, index: number, moreThanOneGPU: boolean): void => { +// if (name === undefined || index === undefined) { +// console.warn('getGPUsFromServer: name or index undefined', name, index); +// return; +// } +// +// let label = 'Temp '; +// label += moreThanOneGPU ? index : ''; +// +// // GPU Temperature Variables +// const monitorTemperatureNElement: TMonitorSettings = { +// id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), +// name: 'Temperature', +// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], +// type: 'boolean', +// label: label, +// symbol: '°', +// title: `${index}: ${name}`, +// defaultValue: true, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.TEMP_START, +// cssColorFinal: Colors.TEMP_END, +// // @ts-ignore +// onChange: async(value: boolean): Promise => { +// this.monitorUI?.updateWidget(monitorTemperatureNElement); +// void await this.updateServerGPU(index, {temperature: value}); +// }, +// }; +// +// this.monitorTemperatureSettings[index] = monitorTemperatureNElement; +// app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); +// }; +// +// createSettingsHDD = (): void => { +// // HDD Variables +// this.monitorHDDElement = { +// id: 'Crystools.ShowHdd', +// name: 'Show HDD Used', +// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], +// type: 'boolean', +// label: 'HDD', +// symbol: '%', +// // tooltip: 'See Partition to show (HDD)', +// defaultValue: false, +// htmlMonitorRef: undefined, +// htmlMonitorSliderRef: undefined, +// htmlMonitorLabelRef: undefined, +// cssColor: Colors.DISK, +// // @ts-ignore +// onChange: async(value: boolean): Promise => { +// this.monitorUI?.updateWidget(this.monitorHDDElement); +// await this.updateServer({switchHDD: value}); +// }, +// }; +// +// this.settingsHDD = { +// id: 'Crystools.WhichHdd', +// name: 'Partition to show', +// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], +// type: 'combo', +// defaultValue: '/', +// data: [], +// // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? +// options: (value: string): any => { +// const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); +// return this.settingsHDD.data.map((m: any) => ({ +// value: m, +// text: m, +// selected: !value ? m === which : m === value, +// })); +// }, +// // @ts-ignore +// onChange: async(value: string): Promise => { +// await this.updateServer({whichHDD: value}); +// }, +// }; +// }; +// +// createSettings = (): void => { +// app.ui.settings.addSetting(this.settingsRate); +// app.ui.settings.addSetting(this.monitorRAMElement); +// app.ui.settings.addSetting(this.monitorCPUElement); +// +// void this.getHDDsFromServer().then((data: string[]): void => { +// // @ts-ignore +// this.settingsHDD.data = data; +// app.ui.settings.addSetting(this.settingsHDD); +// }); +// app.ui.settings.addSetting(this.monitorHDDElement); +// +// void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { +// let moreThanOneGPU = false; +// if (gpus.length > 1) { +// moreThanOneGPU = true; +// } +// +// gpus?.forEach(({name, index}) => { +// +// this.createSettingsGPUTemp(name, index, moreThanOneGPU); +// this.createSettingsGPUVRAM(name, index, moreThanOneGPU); +// this.createSettingsGPUUsage(name, index, moreThanOneGPU); +// +// }); +// }); +// }; +// +// updateDisplay = (): void => { +// console.log('updateDisplay'); +// const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); +// +// if (newMenu !== this.newMenu) { +// this.newMenu = newMenu; +// +// if (this.monitorUI) { +// this.monitorUI.newMenu = this.newMenu; +// } +// +// if (this.newMenu === NewMenuOptions.Disabled) { +// this.setup(); +// } +// } +// }; +// +// updateServer = async(data: TStatsSettings): Promise => { +// const resp = await api.fetchApi('/crystools/monitor', { +// method: 'PATCH', +// body: JSON.stringify(data), +// cache: 'no-store', +// }); +// if (resp.status === 200) { +// return await resp.text(); +// } +// throw new Error(resp.statusText); +// }; +// +// updateServerGPU = async(index: number, data: TGpuSettings): Promise => { +// const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { +// method: 'PATCH', +// body: JSON.stringify(data), +// cache: 'no-store', +// }); +// if (resp.status === 200) { +// return await resp.text(); +// } +// throw new Error(resp.statusText); +// }; +// +// getHDDsFromServer = async(): Promise => { +// return this.getDataFromServer('HDD'); +// }; +// +// getGPUsFromServer = async(): Promise => { +// return this.getDataFromServer('GPU'); +// }; +// +// getDataFromServer = async (what: string): Promise => { +// const resp = await api.fetchApi(`/crystools/monitor/${what}`, { +// method: 'GET', +// cache: 'no-store', +// }); +// if (resp.status === 200) { +// return await resp.json(); +// } +// throw new Error(resp.statusText); +// }; +// +// setup(): void { +// console.log('setup'); +// if (this.monitorUI) { +// return; +// } +// console.log('setup nuevo'); +// const currentRate = +// parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); +// +// this.monitorUI = new MonitorUI( +// this.monitorCPUElement, +// this.monitorRAMElement, +// this.monitorHDDElement, +// this.monitorGPUSettings, +// this.monitorVRAMSettings, +// this.monitorTemperatureSettings, +// currentRate, +// ); +// +// this.registerListeners(); +// } +// +// registerListeners = (): void => { +// api.addEventListener('crystools.monitor', (event: CustomEvent) => { +// if (event?.detail === undefined) { +// return; +// } +// this.monitorUI.updateAllMonitors(event.detail); +// }, false); +// }; +// } +// +// const crystoolsMonitor = new CrystoolsMonitor(); +// app.registerExtension({ +// name: crystoolsMonitor.idExtensionName, +// setup: crystoolsMonitor.setup.bind(crystoolsMonitor), +// }); diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts index 124ae33..e69de29 100644 --- a/web/monitorUI.d.ts +++ b/web/monitorUI.d.ts @@ -1,20 +0,0 @@ -import { ProgressBarUIBase } from './progressBarUI.js'; -export declare class MonitorUI extends ProgressBarUIBase { - private monitorCPUElement; - private monitorRAMElement; - private monitorHDDElement; - private monitorGPUSettings; - private monitorVRAMSettings; - private monitorTemperatureSettings; - private currentRate; - constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number); - refreshDisplay: () => void; - createDOM: () => void; - updateAllWidget: () => void; - updateWidget: (monitorSettings: TMonitorSettings) => void; - updateAllMonitors: (data: TStatsData) => void; - updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; - updateAllAnimationDuration: (value: number) => void; - updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; - createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; -} diff --git a/web/monitorUI.js b/web/monitorUI.js index 8816b70..3918c74 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,241 +1 @@ -import { app } from './comfy/index.js'; -import { ProgressBarUIBase } from './progressBarUI.js'; -export class MonitorUI extends ProgressBarUIBase { - constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { - super(); - Object.defineProperty(this, "monitorCPUElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorCPUElement - }); - Object.defineProperty(this, "monitorRAMElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorRAMElement - }); - Object.defineProperty(this, "monitorHDDElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorHDDElement - }); - Object.defineProperty(this, "monitorGPUSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorGPUSettings - }); - Object.defineProperty(this, "monitorVRAMSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorVRAMSettings - }); - Object.defineProperty(this, "monitorTemperatureSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorTemperatureSettings - }); - Object.defineProperty(this, "currentRate", { - enumerable: true, - configurable: true, - writable: true, - value: currentRate - }); - Object.defineProperty(this, "refreshDisplay", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.updateAllWidget(); - } - }); - Object.defineProperty(this, "createDOM", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); - this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); - this.monitorTemperatureSettings[index] && - this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); - }); - this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); - this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); - } - }); - Object.defineProperty(this, "updateAllWidget", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - } - }); - Object.defineProperty(this, "updateWidget", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - } - }); - Object.defineProperty(this, "updateAllMonitors", { - enumerable: true, - configurable: true, - writable: true, - value: (data) => { - this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); - if (data.gpus === undefined || data.gpus.length === 0) { - console.warn('UpdateAllMonitors: no GPU data'); - return; - } - this.monitorGPUSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.gpu_utilization); - } - else { - } - }); - this.monitorVRAMSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.vram_used_percent); - } - else { - } - }); - this.monitorTemperatureSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - return; - } - this.updateMonitor(monitorSettings, gpu.gpu_temperature); - if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { - monitorSettings.htmlMonitorSliderRef.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; - } - } - else { - } - }); - } - }); - Object.defineProperty(this, "updateMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, percent) => { - if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { - return; - } - monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; - monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; - } - }); - Object.defineProperty(this, "updateAllAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - this.updatedAnimationDuration(this.monitorCPUElement, value); - this.updatedAnimationDuration(this.monitorRAMElement, value); - this.updatedAnimationDuration(this.monitorHDDElement, value); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - } - }); - Object.defineProperty(this, "updatedAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, value) => { - const slider = monitorSettings.htmlMonitorSliderRef; - if (!slider) { - return; - } - slider.style.transition = `width ${value.toFixed(1)}s`; - } - }); - Object.defineProperty(this, "createMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - if (!monitorSettings) { - return document.createElement('div'); - } - const htmlMain = document.createElement('div'); - htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.classList.add('crystools-monitor'); - monitorSettings.htmlMonitorRef = htmlMain; - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.classList.add('crystools-text'); - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.classList.add('crystools-content'); - htmlMain.append(htmlMonitorContent); - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.classList.add('crystools-slider'); - if (monitorSettings.cssColorFinal) { - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } - else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.classList.add('crystools-label'); - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - htmlMonitorLabel.innerHTML = '0%'; - return monitorSettings.htmlMonitorRef; - } - }); - this.createDOM(); - } -} +"use strict"; diff --git a/web/monitorUI.ts b/web/monitorUI.ts index 5b40235..90e9e0e 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -1,213 +1,240 @@ -import { app } from './comfy/index.js'; -import { ProgressBarUIBase } from './progressBarUI.js'; - -export class MonitorUI extends ProgressBarUIBase { - constructor( - private monitorCPUElement: TMonitorSettings, - private monitorRAMElement: TMonitorSettings, - private monitorHDDElement: TMonitorSettings, - private monitorGPUSettings: TMonitorSettings[], - private monitorVRAMSettings: TMonitorSettings[], - private monitorTemperatureSettings: TMonitorSettings[], - private currentRate: number - ) { - super(); - this.createDOM(); - } - - refreshDisplay = (): void => { - // console.log('refreshDisplay'); - this.updateAllWidget(); - }; - - override createDOM = (): void => { - this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); - - // gpu0 > gpu1 > vram0 > vram1 - // this.monitorGPUSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - // this.monitorVRAMSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - // this.monitorTemperatureSettings.forEach((monitorSettings) => { - // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); - // }); - - // gpu0 > vram0 > gpu1 > vram1 - this.monitorGPUSettings.forEach((_monitorSettings, index) => { - this.monitorGPUSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); - this.monitorVRAMSettings[index] && this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); - this.monitorTemperatureSettings[index] && - this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); - }); - - this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); - - this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); - }; - - - updateAllWidget = (): void => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - }; - - /** - * for the settings menu - * @param monitorSettings - */ - updateWidget = (monitorSettings: TMonitorSettings): void => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - }; - - updateAllMonitors = (data: TStatsData): void => { - // console.log('updateAllMonitors', data); - this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); - - if (data.gpus === undefined || data.gpus.length === 0) { - console.warn('UpdateAllMonitors: no GPU data'); - return; - } - - this.monitorGPUSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.gpu_utilization); - } else { - // console.error('UpdateAllMonitors: no GPU data for index', index); - } - }); - - this.monitorVRAMSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.vram_used_percent); - } else { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - } - }); - - this.monitorTemperatureSettings.forEach((monitorSettings, index) => { - if (data.gpus[index]) { - const gpu = data.gpus[index]; - if (gpu === undefined) { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - return; - } - - this.updateMonitor(monitorSettings, gpu.gpu_temperature); - if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ - monitorSettings.htmlMonitorSliderRef.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; - } - } else { - // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - } - }); - }; - - updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { - if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { - return; - } - - monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; - monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; - }; - - updateAllAnimationDuration = (value: number): void => { - this.updatedAnimationDuration(this.monitorCPUElement, value); - this.updatedAnimationDuration(this.monitorRAMElement, value); - this.updatedAnimationDuration(this.monitorHDDElement, value); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - }); - }; - - updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { - const slider = monitorSettings.htmlMonitorSliderRef; - if (!slider) { - return; - } - - slider.style.transition = `width ${value.toFixed(1)}s`; - }; - - - createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { - if (!monitorSettings) { - // just for typescript - return document.createElement('div'); - } - const htmlMain = document.createElement('div'); - htmlMain.setAttribute('id', monitorSettings.id); - htmlMain.classList.add('crystools-monitor'); - monitorSettings.htmlMonitorRef = htmlMain; - - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.classList.add('crystools-text'); - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.classList.add('crystools-content'); - htmlMain.append(htmlMonitorContent); - - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.classList.add('crystools-slider'); - if(monitorSettings.cssColorFinal){ - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.classList.add('crystools-label'); - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - htmlMonitorLabel.innerHTML = '0%'; - return monitorSettings.htmlMonitorRef; - }; -} +// import { app } from './comfy/index.js'; +// import { ProgressBarUIBase } from './progressBarUIBase.js'; +// +// export class MonitorUI extends ProgressBarUIBase { +// private htmlContainer: HTMLDivElement; +// private htmlIdCrystoolsRoot = 'crystools-root'; +// private htmlClassParentElement = 'comfyui-menu-push'; +// +// constructor( +// private monitorCPUElement: TMonitorSettings, +// private monitorRAMElement: TMonitorSettings, +// private monitorHDDElement: TMonitorSettings, +// private monitorGPUSettings: TMonitorSettings[], +// private monitorVRAMSettings: TMonitorSettings[], +// private monitorTemperatureSettings: TMonitorSettings[], +// private currentRate: number +// ) { +// super(); +// this.createRootOldMenu(); +// this.createDOM(); +// console.log('MonitorUI created', this.newMenu); +// } +// +// override createDOM = (): void => { +// this.createDOMOldMenu(); +// this.createDOMNewMenu(); +// }; +// +// createDOMNewMenu = (): void => { +// this.htmlContainer = document.createElement('div'); +// this.htmlContainer.setAttribute('id', this.htmlIdCrystoolsRoot); +// +// // the best parentElement: +// const parentElement = document.getElementsByClassName(this.htmlClassParentElement)[0]; +// parentElement?.insertAdjacentElement('afterend', this.htmlContainer); +// +// this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); +// // this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); +// }; +// +// createDOMOldMenu = (): void => { +// this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); +// this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); +// +// // gpu0 > gpu1 > vram0 > vram1 +// // this.monitorGPUSettings.forEach((monitorSettings) => { +// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); +// // }); +// // this.monitorVRAMSettings.forEach((monitorSettings) => { +// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); +// // }); +// // this.monitorTemperatureSettings.forEach((monitorSettings) => { +// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); +// // }); +// +// // gpu0 > vram0 > gpu1 > vram1 +// this.monitorGPUSettings.forEach((_monitorSettings, index) => { +// this.monitorGPUSettings[index] && +// this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); +// this.monitorVRAMSettings[index] && +// this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); +// this.monitorTemperatureSettings[index] && +// this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); +// }); +// +// this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); +// +// this.updateAllAnimationDuration(this.currentRate); +// this.updateAllWidget(); +// }; +// +// +// refreshDisplay = (): void => { +// // console.log('refreshDisplay'); +// this.updateAllWidget(); +// }; +// +// +// updateAllWidget = (): void => { +// this.updateWidget(this.monitorCPUElement); +// this.updateWidget(this.monitorRAMElement); +// this.updateWidget(this.monitorHDDElement); +// +// this.monitorGPUSettings.forEach((monitorSettings) => { +// monitorSettings && this.updateWidget(monitorSettings); +// }); +// this.monitorVRAMSettings.forEach((monitorSettings) => { +// monitorSettings && this.updateWidget(monitorSettings); +// }); +// this.monitorTemperatureSettings.forEach((monitorSettings) => { +// monitorSettings && this.updateWidget(monitorSettings); +// }); +// }; +// +// /** +// * for the settings menu +// * @param monitorSettings +// */ +// updateWidget = (monitorSettings: TMonitorSettings): void => { +// const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); +// if (monitorSettings.htmlMonitorRef) { +// monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; +// } +// }; +// +// updateAllMonitors = (data: TStatsData): void => { +// // console.log('updateAllMonitors', data); +// this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); +// this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); +// this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); +// +// if (data.gpus === undefined || data.gpus.length === 0) { +// console.warn('UpdateAllMonitors: no GPU data'); +// return; +// } +// +// this.monitorGPUSettings.forEach((monitorSettings, index) => { +// if (data.gpus[index]) { +// const gpu = data.gpus[index]; +// if (gpu === undefined) { +// // console.error('UpdateAllMonitors: no GPU data for index', index); +// return; +// } +// +// this.updateMonitor(monitorSettings, gpu.gpu_utilization); +// } else { +// // console.error('UpdateAllMonitors: no GPU data for index', index); +// } +// }); +// +// this.monitorVRAMSettings.forEach((monitorSettings, index) => { +// if (data.gpus[index]) { +// const gpu = data.gpus[index]; +// if (gpu === undefined) { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// return; +// } +// +// this.updateMonitor(monitorSettings, gpu.vram_used_percent); +// } else { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// } +// }); +// +// this.monitorTemperatureSettings.forEach((monitorSettings, index) => { +// if (data.gpus[index]) { +// const gpu = data.gpus[index]; +// if (gpu === undefined) { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// return; +// } +// +// this.updateMonitor(monitorSettings, gpu.gpu_temperature); +// if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ +// monitorSettings.htmlMonitorSliderRef.style.backgroundColor = +// `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; +// } +// } else { +// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); +// } +// }); +// }; +// +// updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { +// if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { +// return; +// } +// +// monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; +// monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; +// }; +// +// updateAllAnimationDuration = (value: number): void => { +// this.updatedAnimationDuration(this.monitorCPUElement, value); +// this.updatedAnimationDuration(this.monitorRAMElement, value); +// this.updatedAnimationDuration(this.monitorHDDElement, value); +// this.monitorGPUSettings.forEach((monitorSettings) => { +// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); +// }); +// this.monitorVRAMSettings.forEach((monitorSettings) => { +// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); +// }); +// this.monitorTemperatureSettings.forEach((monitorSettings) => { +// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); +// }); +// }; +// +// updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { +// const slider = monitorSettings.htmlMonitorSliderRef; +// if (!slider) { +// return; +// } +// +// slider.style.transition = `width ${value.toFixed(1)}s`; +// }; +// +// +// createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { +// if (!monitorSettings) { +// // just for typescript +// return document.createElement('div'); +// } +// +// const htmlMain = document.createElement('div'); +// htmlMain.classList.add(monitorSettings.id); +// htmlMain.classList.add('crystools-monitor'); +// monitorSettings.htmlMonitorRef = htmlMain; +// +// if (monitorSettings.title) { +// htmlMain.title = monitorSettings.title; +// } +// +// const htmlMonitorText = document.createElement('div'); +// htmlMonitorText.classList.add('crystools-text'); +// htmlMonitorText.innerHTML = monitorSettings.label; +// htmlMain.append(htmlMonitorText); +// +// const htmlMonitorContent = document.createElement('div'); +// htmlMonitorContent.classList.add('crystools-content'); +// htmlMain.append(htmlMonitorContent); +// +// const htmlMonitorSlider = document.createElement('div'); +// htmlMonitorSlider.classList.add('crystools-slider'); +// if(monitorSettings.cssColorFinal){ +// htmlMonitorSlider.style.backgroundColor = +// `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; +// } else { +// htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; +// } +// monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; +// htmlMonitorContent.append(htmlMonitorSlider); +// +// const htmlMonitorLabel = document.createElement('div'); +// htmlMonitorLabel.classList.add('crystools-label'); +// monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; +// htmlMonitorContent.append(htmlMonitorLabel); +// htmlMonitorLabel.innerHTML = '0%'; +// return monitorSettings.htmlMonitorRef; +// }; +// } diff --git a/web/progressBar.js b/web/progressBar.js index d73f560..d6533d9 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -1,6 +1,7 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; -import { EStatus, NewMenuOptions, ProgressBarUI } from './progressBarUI.js'; +import { ProgressBarUI } from './progressBarUI.js'; +import { EStatus, NewMenuOptions } from './progressBarUIBase.js'; class CrystoolsProgressBar { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -27,12 +28,6 @@ class CrystoolsProgressBar { writable: true, value: commonPrefix }); - Object.defineProperty(this, "htmlIdCrystoolsProgressBarContainer", { - enumerable: true, - configurable: true, - writable: true, - value: 'crystools-progress-bar-container' - }); Object.defineProperty(this, "newMenu", { enumerable: true, configurable: true, @@ -63,18 +58,6 @@ class CrystoolsProgressBar { writable: true, value: 0 }); - Object.defineProperty(this, "htmlProgressSliderRef", { - enumerable: true, - configurable: true, - writable: true, - value: undefined - }); - Object.defineProperty(this, "htmlProgressLabelRef", { - enumerable: true, - configurable: true, - writable: true, - value: undefined - }); Object.defineProperty(this, "progressBarUI", { enumerable: true, configurable: true, @@ -93,38 +76,29 @@ class CrystoolsProgressBar { tooltip: 'This apply only on old menu', type: 'boolean', defaultValue: this.defaultShowStatus, - onChange: this.showProgressBar, + onChange: this.progressBarUI.render, }); } }); - Object.defineProperty(this, "showProgressBar", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - if (this.newMenu === NewMenuOptions.Disabled) { - const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); - if (container) { - container.style.display = value ? 'block' : 'none'; - } - } - } - }); Object.defineProperty(this, "updateDisplay", { enumerable: true, configurable: true, writable: true, value: () => { + if (!this.progressBarUI.show) { + return; + } const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; if (this.newMenu === NewMenuOptions.Disabled) { this.setup(); } + else { + this.progressBarUI.show = false; + } } - if (this.newMenu === NewMenuOptions.Disabled) { - this.progressBarUI?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); - } + this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } }); Object.defineProperty(this, "registerListeners", { @@ -183,22 +157,16 @@ class CrystoolsProgressBar { } }); this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - window.addEventListener('resize', () => this.updateDisplay()); - this.createSettings(); - this.updateDisplay(); } setup() { if (this.progressBarUI) { - this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); + this.progressBarUI.render(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); return; } - if (this.newMenu !== NewMenuOptions.Disabled) { - return; - } - this.progressBarUI = new ProgressBarUI(this.htmlIdCrystoolsProgressBarContainer, this.centerNode); - this.htmlProgressSliderRef = this.progressBarUI.htmlProgressSliderRef; - this.htmlProgressLabelRef = this.progressBarUI.htmlProgressLabelRef; - this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + this.progressBarUI = new ProgressBarUI(this.centerNode, (this.newMenu === NewMenuOptions.Disabled)); + this.createSettings(); + this.updateDisplay(); this.registerListeners(); } } diff --git a/web/progressBar.ts b/web/progressBar.ts index 914ee5e..f00f459 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -1,13 +1,13 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; -import { EStatus, NewMenuOptions, ProgressBarUI } from './progressBarUI.js'; +import { ProgressBarUI } from './progressBarUI.js'; +import { EStatus, NewMenuOptions } from './progressBarUIBase.js'; class CrystoolsProgressBar { idExtensionName = 'Crystools.progressBar'; idShowProgressBar = 'Crystools.ProgressBar'; defaultShowStatus = true; menuPrefix = commonPrefix; - htmlIdCrystoolsProgressBarContainer = 'crystools-progress-bar-container'; newMenu: NewMenuOptions = NewMenuOptions.Disabled; currentStatus = EStatus.executed; @@ -15,16 +15,10 @@ class CrystoolsProgressBar { currentNode?: number = undefined; timeStart = 0; - htmlProgressSliderRef?: HTMLDivElement = undefined; - htmlProgressLabelRef?: HTMLDivElement = undefined; - progressBarUI: ProgressBarUI; constructor() { this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - window.addEventListener('resize', () => this.updateDisplay()); - this.createSettings(); - this.updateDisplay(); } // not on setup because this affect the order on settings, I prefer to options at first @@ -36,23 +30,15 @@ class CrystoolsProgressBar { tooltip: 'This apply only on old menu', type: 'boolean', defaultValue: this.defaultShowStatus, - onChange: this.showProgressBar, + onChange: this.progressBarUI.render, }); }; - showProgressBar = (value: boolean): void => { - if (this.newMenu === NewMenuOptions.Disabled) { - const container = document.getElementById(this.htmlIdCrystoolsProgressBarContainer); - - // validation because this run before setup - if (container) { - container.style.display = value ? 'block' : 'none'; - } + updateDisplay = (): void => { + if(!this.progressBarUI.show){ + return; } - }; - - updateDisplay = (): void => { const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { @@ -60,32 +46,26 @@ class CrystoolsProgressBar { if (this.newMenu === NewMenuOptions.Disabled) { this.setup(); + } else { + this.progressBarUI.show = false; } } - if (this.newMenu === NewMenuOptions.Disabled) { - this.progressBarUI?.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); - } - + this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); }; + // automatically called by ComfyUI setup(): void { if (this.progressBarUI) { - this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); - return; - } - if (this.newMenu !== NewMenuOptions.Disabled) { + this.progressBarUI.render(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); return; } - this.progressBarUI = new ProgressBarUI( - this.htmlIdCrystoolsProgressBarContainer, - this.centerNode); + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + this.progressBarUI = new ProgressBarUI(this.centerNode, (this.newMenu === NewMenuOptions.Disabled)); - this.htmlProgressSliderRef = this.progressBarUI.htmlProgressSliderRef; - this.htmlProgressLabelRef = this.progressBarUI.htmlProgressLabelRef; - - this.showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); + this.createSettings(); + this.updateDisplay(); this.registerListeners(); } diff --git a/web/progressBarUI.d.ts b/web/progressBarUI.d.ts index b4fd5a3..01a6c39 100644 --- a/web/progressBarUI.d.ts +++ b/web/progressBarUI.d.ts @@ -1,32 +1,13 @@ -export declare enum EStatus { - executing = "Executing", - executed = "Executed", - execution_error = "Execution error" -} -export declare enum NewMenuOptions { - 'Disabled' = "Disabled", - 'Top' = "Top", - 'Bottom' = "Bottom" -} -export declare abstract class ProgressBarUIBase { - protected htmlIdCrystoolsRoot: string; - protected htmlClassCrystoolsMonitorContainer: string; - protected htmlContainer: HTMLDivElement; - protected newMenu: NewMenuOptions; - protected constructor(); - createRoot(): void; - abstract createDOM(): void; -} +import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export declare class ProgressBarUI extends ProgressBarUIBase { - private htmlIdCrystoolsProgressBarContainer; private centerNode; htmlProgressSliderRef: HTMLDivElement; htmlProgressLabelRef: HTMLDivElement; currentStatus: EStatus; timeStart: number; currentProgress: number; - constructor(htmlIdCrystoolsProgressBarContainer: string, centerNode: () => void); + constructor(centerNode: () => void, show: boolean); createDOM: () => void; - refreshDisplay: () => void; updateDisplay: (currentStatus: EStatus, timeStart: number, currentProgress: number) => void; + private refreshDisplay; } diff --git a/web/progressBarUI.js b/web/progressBarUI.js index 7010de0..19d7d4a 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,69 +1,7 @@ -import { app } from './comfy/index.js'; -export var EStatus; -(function (EStatus) { - EStatus["executing"] = "Executing"; - EStatus["executed"] = "Executed"; - EStatus["execution_error"] = "Execution error"; -})(EStatus || (EStatus = {})); -export var NewMenuOptions; -(function (NewMenuOptions) { - NewMenuOptions["Disabled"] = "Disabled"; - NewMenuOptions["Top"] = "Top"; - NewMenuOptions["Bottom"] = "Bottom"; -})(NewMenuOptions || (NewMenuOptions = {})); -export class ProgressBarUIBase { - constructor() { - Object.defineProperty(this, "htmlIdCrystoolsRoot", { - enumerable: true, - configurable: true, - writable: true, - value: 'crystools-root' - }); - Object.defineProperty(this, "htmlClassCrystoolsMonitorContainer", { - enumerable: true, - configurable: true, - writable: true, - value: 'crystools-monitor-container' - }); - Object.defineProperty(this, "htmlContainer", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "newMenu", { - enumerable: true, - configurable: true, - writable: true, - value: NewMenuOptions.Disabled - }); - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - if (this.newMenu === NewMenuOptions.Disabled) { - this.createRoot(); - } - } - createRoot() { - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - const parentElement = document.getElementById('queue-button'); - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); - } - this.htmlContainer = document.createElement('div'); - this.htmlContainer.classList.add(this.htmlClassCrystoolsMonitorContainer); - ctoolsRoot.append(this.htmlContainer); - } -} +import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export class ProgressBarUI extends ProgressBarUIBase { - constructor(htmlIdCrystoolsProgressBarContainer, centerNode) { - super(); - Object.defineProperty(this, "htmlIdCrystoolsProgressBarContainer", { - enumerable: true, - configurable: true, - writable: true, - value: htmlIdCrystoolsProgressBarContainer - }); + constructor(centerNode, show) { + super('queue-button', 'crystools-root-old', show); Object.defineProperty(this, "centerNode", { enumerable: true, configurable: true, @@ -106,7 +44,6 @@ export class ProgressBarUI extends ProgressBarUIBase { writable: true, value: () => { const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); htmlContainer.addEventListener('click', this.centerNode); this.htmlContainer.append(htmlContainer); @@ -125,21 +62,14 @@ export class ProgressBarUI extends ProgressBarUIBase { progressBar.append(this.htmlProgressLabelRef); } }); - Object.defineProperty(this, "refreshDisplay", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - if (this.newMenu === NewMenuOptions.Disabled) { - this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); - } - } - }); Object.defineProperty(this, "updateDisplay", { enumerable: true, configurable: true, writable: true, value: (currentStatus, timeStart, currentProgress) => { + if (!this.show) { + return; + } if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); return; @@ -166,8 +96,17 @@ export class ProgressBarUI extends ProgressBarUIBase { } } }); - if (this.newMenu === NewMenuOptions.Disabled) { - this.createDOM(); - } + Object.defineProperty(this, "refreshDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + if (this.show) { + this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + } + } + }); + window.addEventListener('resize', this.refreshDisplay); + this.createDOM(); } } diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index fb9b9b2..ff39edd 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -1,50 +1,4 @@ -import { app } from './comfy/index.js'; - -export enum EStatus { - executing = 'Executing', - executed = 'Executed', - execution_error = 'Execution error', -} - -export enum NewMenuOptions { - 'Disabled' = 'Disabled', - 'Top' = 'Top', - 'Bottom' = 'Bottom', -} - -export abstract class ProgressBarUIBase { - protected htmlIdCrystoolsRoot = 'crystools-root'; - protected htmlClassCrystoolsMonitorContainer = 'crystools-monitor-container'; - protected htmlContainer: HTMLDivElement; - protected newMenu: NewMenuOptions = NewMenuOptions.Disabled; - - protected constructor() { - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - if(this.newMenu === NewMenuOptions.Disabled) { - this.createRoot(); - } - } - - createRoot(): void { - // IMPORTANT duplicate by progressbar and crystools-save - let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot); - - // the best parentElement: - const parentElement = document.getElementById('queue-button'); - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); - } - - this.htmlContainer = document.createElement('div'); - this.htmlContainer.classList.add(this.htmlClassCrystoolsMonitorContainer); - ctoolsRoot.append(this.htmlContainer); - } - - // abstract refreshDisplay(): void; - abstract createDOM(): void; -} +import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export class ProgressBarUI extends ProgressBarUIBase{ htmlProgressSliderRef: HTMLDivElement; @@ -54,18 +8,16 @@ export class ProgressBarUI extends ProgressBarUIBase{ currentProgress: number; constructor ( - private htmlIdCrystoolsProgressBarContainer: string, - private centerNode: () => void + private centerNode: () => void, + show: boolean, ) { - super(); - if(this.newMenu === NewMenuOptions.Disabled) { - this.createDOM(); - } + super('queue-button', 'crystools-root-old', show); + window.addEventListener('resize', this.refreshDisplay); + this.createDOM(); } createDOM = (): void => { const htmlContainer = document.createElement('div'); - htmlContainer.setAttribute('id', this.htmlIdCrystoolsProgressBarContainer); htmlContainer.setAttribute('title', 'click to see the current working node'); htmlContainer.addEventListener('click', this.centerNode); this.htmlContainer.append(htmlContainer); @@ -87,13 +39,11 @@ export class ProgressBarUI extends ProgressBarUIBase{ progressBar.append(this.htmlProgressLabelRef); }; - refreshDisplay = (): void => { - if(this.newMenu === NewMenuOptions.Disabled) { - this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); - } - }; - + // eslint-disable-next-line complexity updateDisplay = (currentStatus: EStatus, timeStart: number, currentProgress: number): void => { + if (!this.show) { + return; + } if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); return; @@ -128,4 +78,10 @@ export class ProgressBarUI extends ProgressBarUIBase{ }; + // not data only display + private refreshDisplay = (): void => { + if (this.show) { + this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + } + }; } diff --git a/web/progressBarUIBase.d.ts b/web/progressBarUIBase.d.ts new file mode 100644 index 0000000..2c7ae28 --- /dev/null +++ b/web/progressBarUIBase.d.ts @@ -0,0 +1,22 @@ +export declare enum EStatus { + executing = "Executing", + executed = "Executed", + execution_error = "Execution error" +} +export declare enum NewMenuOptions { + 'Disabled' = "Disabled", + 'Top' = "Top", + 'Bottom' = "Bottom" +} +export declare abstract class ProgressBarUIBase { + parentId: string; + rootId: string; + show: boolean; + protected htmlContainer: HTMLDivElement; + protected htmlClassMonitor: string; + protected constructor(parentId: string, rootId: string, show: boolean); + private createRoot; + render: (value: boolean) => void; + abstract createDOM(): void; + abstract updateDisplay(currentStatus: EStatus, timeStart: number, currentProgress: number): void; +} diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js new file mode 100644 index 0000000..8d51e1d --- /dev/null +++ b/web/progressBarUIBase.js @@ -0,0 +1,73 @@ +export var EStatus; +(function (EStatus) { + EStatus["executing"] = "Executing"; + EStatus["executed"] = "Executed"; + EStatus["execution_error"] = "Execution error"; +})(EStatus || (EStatus = {})); +export var NewMenuOptions; +(function (NewMenuOptions) { + NewMenuOptions["Disabled"] = "Disabled"; + NewMenuOptions["Top"] = "Top"; + NewMenuOptions["Bottom"] = "Bottom"; +})(NewMenuOptions || (NewMenuOptions = {})); +export class ProgressBarUIBase { + constructor(parentId, rootId, show) { + Object.defineProperty(this, "parentId", { + enumerable: true, + configurable: true, + writable: true, + value: parentId + }); + Object.defineProperty(this, "rootId", { + enumerable: true, + configurable: true, + writable: true, + value: rootId + }); + Object.defineProperty(this, "show", { + enumerable: true, + configurable: true, + writable: true, + value: show + }); + Object.defineProperty(this, "htmlContainer", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "htmlClassMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: 'crystools-monitor-container' + }); + Object.defineProperty(this, "createRoot", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + let ctoolsRoot = document.getElementById(this.rootId); + if (!ctoolsRoot) { + ctoolsRoot = document.createElement('div'); + ctoolsRoot.setAttribute('id', this.rootId); + const parentElement = document.getElementById(this.parentId); + parentElement?.insertAdjacentElement('afterend', ctoolsRoot); + } + this.htmlContainer = document.createElement('div'); + this.htmlContainer.classList.add(this.htmlClassMonitor); + ctoolsRoot.append(this.htmlContainer); + } + }); + Object.defineProperty(this, "render", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + this.show = value; + this.htmlContainer.style.display = this.show ? 'block' : 'none'; + } + }); + this.createRoot(); + } +} diff --git a/web/progressBarUIBase.ts b/web/progressBarUIBase.ts new file mode 100644 index 0000000..253f3e9 --- /dev/null +++ b/web/progressBarUIBase.ts @@ -0,0 +1,50 @@ +export enum EStatus { + executing = 'Executing', + executed = 'Executed', + execution_error = 'Execution error', +} + +export enum NewMenuOptions { + 'Disabled' = 'Disabled', + 'Top' = 'Top', + 'Bottom' = 'Bottom', +} + +export abstract class ProgressBarUIBase { + protected htmlContainer: HTMLDivElement; + protected htmlClassMonitor = 'crystools-monitor-container'; + + protected constructor( + public parentId: string, + public rootId: string, + public show: boolean, + ) { + this.createRoot(); + } + + private createRoot = (): void => { + // IMPORTANT duplicate on crystools-save + let ctoolsRoot = document.getElementById(this.rootId); + if (!ctoolsRoot) { + ctoolsRoot = document.createElement('div'); + ctoolsRoot.setAttribute('id', this.rootId); + + // the best parentElement: + const parentElement = document.getElementById(this.parentId); + parentElement?.insertAdjacentElement('afterend', ctoolsRoot); + } + + this.htmlContainer = document.createElement('div'); + this.htmlContainer.classList.add(this.htmlClassMonitor); + ctoolsRoot.append(this.htmlContainer); + }; + + // remember it can't have more parameters because it is used on settings automatically + public render = (value: boolean): void => { + this.show = value; + this.htmlContainer.style.display = this.show ? 'block' : 'none'; + }; + + abstract createDOM(): void; + abstract updateDisplay(currentStatus: EStatus, timeStart: number, currentProgress: number): void; +} From 83d210f2eef9ff3f0d6a708ca20cc768c6952e8d Mon Sep 17 00:00:00 2001 From: Crystian Date: Sun, 22 Sep 2024 19:36:31 +0200 Subject: [PATCH 17/31] starting with horizontal... finally34... --- __init__.py | 2 +- core/version.py | 2 +- general/gpu.py | 20 +- pyproject.toml | 2 +- version | 2 +- web/monitor.css | 12 +- web/monitor.d.ts | 1 + web/monitor.js | 483 +++++++++++++++++++++- web/monitor.ts | 823 +++++++++++++++++++------------------ web/monitorUI.d.ts | 0 web/monitorUI.js | 1 - web/monitorUI.ts | 240 ----------- web/monitorVerticalUI.d.ts | 22 + web/monitorVerticalUI.js | 273 ++++++++++++ web/monitorVerticalUI.ts | 232 +++++++++++ web/progressBar.js | 43 +- web/progressBar.ts | 24 +- web/progressBarUI.d.ts | 5 +- web/progressBarUI.js | 25 +- web/progressBarUI.ts | 29 +- web/progressBarUIBase.d.ts | 7 +- web/progressBarUIBase.js | 20 +- web/progressBarUIBase.ts | 15 +- 23 files changed, 1532 insertions(+), 751 deletions(-) delete mode 100644 web/monitorUI.d.ts delete mode 100644 web/monitorUI.js delete mode 100644 web/monitorUI.ts create mode 100644 web/monitorVerticalUI.d.ts create mode 100644 web/monitorVerticalUI.js create mode 100644 web/monitorVerticalUI.ts diff --git a/__init__.py b/__init__.py index 326a62a..12b2ec0 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ @author: Crystian @title: Crystools @nickname: Crystools -@version: 1.17.0 +@version: 1.18.0 @project: "https://github.com/crystian/ComfyUI-Crystools", @description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia """ diff --git a/core/version.py b/core/version.py index 89a555d..9bc7482 100644 --- a/core/version.py +++ b/core/version.py @@ -1 +1 @@ -version = "1.17.0" +version = "1.18.0" diff --git a/general/gpu.py b/general/gpu.py index f14d2c6..786a3af 100644 --- a/general/gpu.py +++ b/general/gpu.py @@ -110,11 +110,11 @@ class CGPUInfo: if self.cudaDevice == 'cpu': gpuType = 'cpu' gpus.append({ - 'gpu_utilization': 0, - 'gpu_temperature': 0, - 'vram_total': 0, - 'vram_used': 0, - 'vram_used_percent': 0, + 'gpu_utilization': -1, + 'gpu_temperature': -1, + 'vram_total': -1, + 'vram_used': -1, + 'vram_used_percent': -1, }) else: gpuType = self.cudaDevice @@ -126,11 +126,11 @@ class CGPUInfo: for deviceIndex in range(self.cudaDevicesFound): deviceHandle = self.deviceGetHandleByIndex(deviceIndex) - gpuUtilization = 0 - vramPercent = 0 - vramUsed = 0 - vramTotal = 0 - gpuTemperature = 0 + gpuUtilization = -1 + vramPercent = -1 + vramUsed = -1 + vramTotal = -1 + gpuTemperature = -1 # GPU Utilization if self.switchGPU and self.gpusUtilization[deviceIndex]: diff --git a/pyproject.toml b/pyproject.toml index 73be846..f971752 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-crystools" description = "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." -version = "1.17.0" +version = "1.18.0" license = { file = "LICENSE" } dependencies = ["deepdiff", "torch", "numpy", "Pillow", "pynvml", "py-cpuinfo"] diff --git a/version b/version index 092afa1..84cc529 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.17.0 +1.18.0 diff --git a/web/monitor.css b/web/monitor.css index ad4b620..0bb150c 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -3,15 +3,19 @@ display: flex; width: 100%; flex-direction: column; + margin: 0; + padding: 0; .crystools-monitor-container { width: 100%; cursor: crosshair; - order: 3; margin: 4px 0; + /* display: flex; by progress bar base */ + flex-wrap: wrap; + flex-direction: column; .crystools-monitor { - margin: 2px 10px; + margin: 1px 10px; height: 12px; position: relative; display: flex; @@ -20,8 +24,10 @@ } .crystools-text { - width: 35px; + width: 40px; font-size: 10px; + text-align: right; + margin-right: 3px; } .crystools-content { diff --git a/web/monitor.d.ts b/web/monitor.d.ts index e69de29..cb0ff5c 100644 --- a/web/monitor.d.ts +++ b/web/monitor.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/web/monitor.js b/web/monitor.js index 3918c74..a2a440f 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1 +1,482 @@ -"use strict"; +import { app, api } from './comfy/index.js'; +import { commonPrefix } from './common.js'; +import { MonitorVerticalUI } from './monitorVerticalUI.js'; +import { Colors } from './styles.js'; +import { convertNumberToPascalCase } from './utils.js'; +import { NewMenuOptions } from './progressBarUIBase.js'; +class CrystoolsMonitor { + constructor() { + Object.defineProperty(this, "idExtensionName", { + enumerable: true, + configurable: true, + writable: true, + value: 'Crystools.monitor' + }); + Object.defineProperty(this, "menuPrefix", { + enumerable: true, + configurable: true, + writable: true, + value: commonPrefix + }); + Object.defineProperty(this, "newMenu", { + enumerable: true, + configurable: true, + writable: true, + value: NewMenuOptions.Disabled + }); + Object.defineProperty(this, "settingsRate", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorCPUElement", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorRAMElement", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorHDDElement", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "settingsHDD", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "monitorGPUSettings", { + enumerable: true, + configurable: true, + writable: true, + value: [] + }); + Object.defineProperty(this, "monitorVRAMSettings", { + enumerable: true, + configurable: true, + writable: true, + value: [] + }); + Object.defineProperty(this, "monitorTemperatureSettings", { + enumerable: true, + configurable: true, + writable: true, + value: [] + }); + Object.defineProperty(this, "monitorVerticalUI", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "createSettingsRate", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.settingsRate = { + id: 'Crystools.RefreshRate', + name: 'Refresh per second', + category: ['Crystools', this.menuPrefix + ' Refresh Rate'], + tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', + type: 'slider', + attrs: { + min: 0, + max: 2, + step: 0.25, + }, + defaultValue: .5, + onChange: async (value) => { + let valueNumber; + try { + valueNumber = parseFloat(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } + catch (error) { + console.error(error); + return; + } + try { + await this.updateServer({ rate: valueNumber }); + } + catch (error) { + console.error(error); + return; + } + if (valueNumber === 0) { + this.monitorVerticalUI.updateDisplay({ + cpu_utilization: 0, + device: 'cpu', + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }); + } + this.monitorVerticalUI?.updateAllAnimationDuration(valueNumber); + }, + }; + } + }); + Object.defineProperty(this, "createSettingsCPU", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.monitorCPUElement = { + id: 'Crystools.ShowCpu', + name: 'CPU Usage', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], + type: 'boolean', + label: 'CPU', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.CPU, + onChange: async (value) => { + this.monitorVerticalUI?.updateWidget(this.monitorCPUElement); + await this.updateServer({ switchCPU: value }); + }, + }; + } + }); + Object.defineProperty(this, "createSettingsRAM", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.monitorRAMElement = { + id: 'Crystools.ShowRam', + name: 'RAM Used', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], + type: 'boolean', + label: 'RAM', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.RAM, + onChange: async (value) => { + this.monitorVerticalUI?.updateWidget(this.monitorRAMElement); + await this.updateServer({ switchRAM: value }); + }, + }; + } + }); + Object.defineProperty(this, "createSettingsGPUUsage", { + enumerable: true, + configurable: true, + writable: true, + value: (name, index, moreThanOneGPU) => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + let label = 'GPU '; + label += moreThanOneGPU ? index : ''; + const monitorGPUNElement = { + id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), + name: ' Usage', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], + type: 'boolean', + label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.GPU, + onChange: async (value) => { + this.monitorVerticalUI?.updateWidget(monitorGPUNElement); + void await this.updateServerGPU(index, { utilization: value }); + }, + }; + this.monitorGPUSettings[index] = monitorGPUNElement; + app.ui.settings.addSetting(this.monitorGPUSettings[index]); + this.monitorVerticalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); + } + }); + Object.defineProperty(this, "createSettingsGPUVRAM", { + enumerable: true, + configurable: true, + writable: true, + value: (name, index, moreThanOneGPU) => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + let label = 'VRAM '; + label += moreThanOneGPU ? index : ''; + const monitorVRAMNElement = { + id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), + name: 'VRAM', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], + type: 'boolean', + label: label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.VRAM, + onChange: async (value) => { + this.monitorVerticalUI?.updateWidget(monitorVRAMNElement); + void await this.updateServerGPU(index, { vram: value }); + }, + }; + this.monitorVRAMSettings[index] = monitorVRAMNElement; + app.ui.settings.addSetting(this.monitorVRAMSettings[index]); + this.monitorVerticalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); + } + }); + Object.defineProperty(this, "createSettingsGPUTemp", { + enumerable: true, + configurable: true, + writable: true, + value: (name, index, moreThanOneGPU) => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + let label = 'Temp '; + label += moreThanOneGPU ? index : ''; + const monitorTemperatureNElement = { + id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), + name: 'Temperature', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], + type: 'boolean', + label: label, + symbol: '°', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.TEMP_START, + cssColorFinal: Colors.TEMP_END, + onChange: async (value) => { + this.monitorVerticalUI?.updateWidget(monitorTemperatureNElement); + void await this.updateServerGPU(index, { temperature: value }); + }, + }; + this.monitorTemperatureSettings[index] = monitorTemperatureNElement; + app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); + this.monitorVerticalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); + } + }); + Object.defineProperty(this, "createSettingsHDD", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.monitorHDDElement = { + id: 'Crystools.ShowHdd', + name: 'Show HDD Used', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], + type: 'boolean', + label: 'HDD', + symbol: '%', + defaultValue: false, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.DISK, + onChange: async (value) => { + this.monitorVerticalUI?.updateWidget(this.monitorHDDElement); + await this.updateServer({ switchHDD: value }); + }, + }; + this.settingsHDD = { + id: 'Crystools.WhichHdd', + name: 'Partition to show', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], + type: 'combo', + defaultValue: '/', + data: [], + options: (value) => { + const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); + return this.settingsHDD.data.map((m) => ({ + value: m, + text: m, + selected: !value ? m === which : m === value, + })); + }, + onChange: async (value) => { + await this.updateServer({ whichHDD: value }); + }, + }; + } + }); + Object.defineProperty(this, "createSettings", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + app.ui.settings.addSetting(this.settingsRate); + app.ui.settings.addSetting(this.monitorRAMElement); + app.ui.settings.addSetting(this.monitorCPUElement); + void this.getHDDsFromServer().then((data) => { + this.settingsHDD.data = data; + app.ui.settings.addSetting(this.settingsHDD); + }); + app.ui.settings.addSetting(this.monitorHDDElement); + void this.getGPUsFromServer().then((gpus) => { + let moreThanOneGPU = false; + if (gpus.length > 1) { + moreThanOneGPU = true; + } + gpus?.forEach(({ name, index }) => { + this.createSettingsGPUTemp(name, index, moreThanOneGPU); + this.createSettingsGPUVRAM(name, index, moreThanOneGPU); + this.createSettingsGPUUsage(name, index, moreThanOneGPU); + }); + this.monitorVerticalUI.orderMonitors(); + }); + } + }); + Object.defineProperty(this, "updateDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + this.monitorVerticalUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); + if (this.monitorVerticalUI.showSection) { + this.setup(); + } + } + } + }); + Object.defineProperty(this, "updateServer", { + enumerable: true, + configurable: true, + writable: true, + value: async (data) => { + const resp = await api.fetchApi('/crystools/monitor', { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + } + }); + Object.defineProperty(this, "updateServerGPU", { + enumerable: true, + configurable: true, + writable: true, + value: async (index, data) => { + const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + } + }); + Object.defineProperty(this, "getHDDsFromServer", { + enumerable: true, + configurable: true, + writable: true, + value: async () => { + return this.getDataFromServer('HDD'); + } + }); + Object.defineProperty(this, "getGPUsFromServer", { + enumerable: true, + configurable: true, + writable: true, + value: async () => { + return this.getDataFromServer('GPU'); + } + }); + Object.defineProperty(this, "getDataFromServer", { + enumerable: true, + configurable: true, + writable: true, + value: async (what) => { + const resp = await api.fetchApi(`/crystools/monitor/${what}`, { + method: 'GET', + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.json(); + } + throw new Error(resp.statusText); + } + }); + Object.defineProperty(this, "setup", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + if (this.monitorVerticalUI) { + return; + } + this.createSettingsRate(); + this.createSettingsCPU(); + this.createSettingsRAM(); + this.createSettingsHDD(); + this.createSettings(); + const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + this.monitorVerticalUI = new MonitorVerticalUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu === NewMenuOptions.Disabled)); + this.updateDisplay(); + this.registerListeners(); + } + }); + Object.defineProperty(this, "registerListeners", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + api.addEventListener('crystools.monitor', (event) => { + if (event?.detail === undefined) { + return; + } + this.monitorVerticalUI.updateDisplay(event.detail); + }, false); + } + }); + window.addEventListener('resize', this.updateDisplay); + } +} +const crystoolsMonitor = new CrystoolsMonitor(); +app.registerExtension({ + name: crystoolsMonitor.idExtensionName, + setup: crystoolsMonitor.setup, +}); diff --git a/web/monitor.ts b/web/monitor.ts index b2766d2..5c215cf 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,411 +1,412 @@ -// import { app, api } from './comfy/index.js'; -// import { commonPrefix } from './common.js'; -// import { MonitorUI } from './monitorUI.js'; -// import { Colors } from './styles.js'; -// import { convertNumberToPascalCase } from './utils.js'; -// import { NewMenuOptions } from './progressBarUIBase.js'; -// -// class CrystoolsMonitor { -// idExtensionName = 'Crystools.monitor'; -// menuPrefix = commonPrefix; -// -// monitorUI: MonitorUI; -// newMenu: NewMenuOptions = NewMenuOptions.Disabled; -// -// settingsRate: TMonitorSettings; -// monitorCPUElement: TMonitorSettings; -// monitorRAMElement: TMonitorSettings; -// monitorHDDElement: TMonitorSettings; -// settingsHDD: TMonitorSettings; -// monitorGPUSettings: TMonitorSettings[] = []; -// monitorVRAMSettings: TMonitorSettings[] = []; -// monitorTemperatureSettings: TMonitorSettings[] = []; -// -// constructor() { -// this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); -// window.addEventListener('resize', () => this.updateDisplay()); -// this.createSettingsRate(); -// this.createSettingsCPU(); -// this.createSettingsRAM(); -// this.createSettingsHDD(); -// this.createSettings(); -// this.updateDisplay(); -// } -// -// createSettingsRate = (): void => { -// this.settingsRate = { -// id: 'Crystools.RefreshRate', -// name: 'Refresh per second', -// category: ['Crystools', this.menuPrefix + ' Refresh Rate'], -// tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', -// type: 'slider', -// attrs: { -// min: 0, -// max: 2, -// step: 0.25, -// }, -// defaultValue: .5, -// // @ts-ignore -// onChange: async(value: string): Promise => { -// let valueNumber: number; -// -// try { -// valueNumber = parseFloat(value); -// if (isNaN(valueNumber)) { -// throw new Error('invalid value'); -// } -// } catch (error) { -// console.error(error); -// return; -// } -// try { -// await this.updateServer({rate: valueNumber}); -// } catch (error) { -// console.error(error); -// return; -// } -// -// if (valueNumber === 0) { -// this.monitorUI.updateAllMonitors({ -// cpu_utilization: 0, -// device: 'cpu', -// -// gpus: [ -// { -// gpu_utilization: 0, -// gpu_temperature: 0, -// vram_total: 0, -// vram_used: 0, -// vram_used_percent: 0, -// }, -// ], -// hdd_total: 0, -// hdd_used: 0, -// hdd_used_percent: 0, -// ram_total: 0, -// ram_used: 0, -// ram_used_percent: 0, -// }); -// } -// -// this.monitorUI?.updateAllAnimationDuration(valueNumber); -// }, -// }; -// }; -// -// createSettingsCPU = (): void => { -// // CPU Variables -// this.monitorCPUElement = { -// id: 'Crystools.ShowCpu', -// name: 'CPU Usage', -// category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], -// type: 'boolean', -// label: 'CPU', -// symbol: '%', -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.CPU, -// // @ts-ignore -// onChange: async(value: boolean): Promise => { -// this.monitorUI?.updateWidget(this.monitorCPUElement); -// await this.updateServer({switchCPU: value}); -// }, -// }; -// }; -// -// createSettingsRAM = (): void => { -// // RAM Variables -// this.monitorRAMElement = { -// id: 'Crystools.ShowRam', -// name: 'RAM Used', -// category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], -// type: 'boolean', -// label: 'RAM', -// symbol: '%', -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.RAM, -// // @ts-ignore -// onChange: async(value: boolean): Promise => { -// this.monitorUI?.updateWidget(this.monitorRAMElement); -// await this.updateServer({switchRAM: value}); -// }, -// }; -// }; -// -// createSettingsGPUUsage = (name: string, index: number, moreThanOneGPU: boolean): void => { -// if (name === undefined || index === undefined) { -// console.warn('getGPUsFromServer: name or index undefined', name, index); -// return; -// } -// -// let label = 'GPU '; -// label += moreThanOneGPU ? index : ''; -// -// const monitorGPUNElement: TMonitorSettings = { -// id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), -// name: ' Usage', -// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], -// type: 'boolean', -// label, -// symbol: '%', -// title: `${index}: ${name}`, -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.GPU, -// // @ts-ignore -// onChange: async(value: boolean): Promise => { -// this.monitorUI?.updateWidget(monitorGPUNElement); -// void await this.updateServerGPU(index, {utilization: value}); -// }, -// }; -// -// this.monitorGPUSettings[index] = monitorGPUNElement; -// app.ui.settings.addSetting(this.monitorGPUSettings[index]); -// }; -// -// createSettingsGPUVRAM = (name: string, index: number, moreThanOneGPU: boolean): void => { -// if (name === undefined || index === undefined) { -// console.warn('getGPUsFromServer: name or index undefined', name, index); -// return; -// } -// -// let label = 'VRAM'; -// label += moreThanOneGPU ? index : ''; -// -// // GPU VRAM Variables -// const monitorVRAMNElement: TMonitorSettings = { -// id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), -// name: 'VRAM', -// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], -// type: 'boolean', -// label: label, -// symbol: '%', -// title: `${index}: ${name}`, -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.VRAM, -// // @ts-ignore -// onChange: async(value: boolean): Promise => { -// this.monitorUI?.updateWidget(monitorVRAMNElement); -// void await this.updateServerGPU(index, {vram: value}); -// }, -// }; -// -// this.monitorVRAMSettings[index] = monitorVRAMNElement; -// app.ui.settings.addSetting(this.monitorVRAMSettings[index]); -// }; -// -// createSettingsGPUTemp = (name: string, index: number, moreThanOneGPU: boolean): void => { -// if (name === undefined || index === undefined) { -// console.warn('getGPUsFromServer: name or index undefined', name, index); -// return; -// } -// -// let label = 'Temp '; -// label += moreThanOneGPU ? index : ''; -// -// // GPU Temperature Variables -// const monitorTemperatureNElement: TMonitorSettings = { -// id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), -// name: 'Temperature', -// category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], -// type: 'boolean', -// label: label, -// symbol: '°', -// title: `${index}: ${name}`, -// defaultValue: true, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.TEMP_START, -// cssColorFinal: Colors.TEMP_END, -// // @ts-ignore -// onChange: async(value: boolean): Promise => { -// this.monitorUI?.updateWidget(monitorTemperatureNElement); -// void await this.updateServerGPU(index, {temperature: value}); -// }, -// }; -// -// this.monitorTemperatureSettings[index] = monitorTemperatureNElement; -// app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); -// }; -// -// createSettingsHDD = (): void => { -// // HDD Variables -// this.monitorHDDElement = { -// id: 'Crystools.ShowHdd', -// name: 'Show HDD Used', -// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], -// type: 'boolean', -// label: 'HDD', -// symbol: '%', -// // tooltip: 'See Partition to show (HDD)', -// defaultValue: false, -// htmlMonitorRef: undefined, -// htmlMonitorSliderRef: undefined, -// htmlMonitorLabelRef: undefined, -// cssColor: Colors.DISK, -// // @ts-ignore -// onChange: async(value: boolean): Promise => { -// this.monitorUI?.updateWidget(this.monitorHDDElement); -// await this.updateServer({switchHDD: value}); -// }, -// }; -// -// this.settingsHDD = { -// id: 'Crystools.WhichHdd', -// name: 'Partition to show', -// category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], -// type: 'combo', -// defaultValue: '/', -// data: [], -// // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? -// options: (value: string): any => { -// const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); -// return this.settingsHDD.data.map((m: any) => ({ -// value: m, -// text: m, -// selected: !value ? m === which : m === value, -// })); -// }, -// // @ts-ignore -// onChange: async(value: string): Promise => { -// await this.updateServer({whichHDD: value}); -// }, -// }; -// }; -// -// createSettings = (): void => { -// app.ui.settings.addSetting(this.settingsRate); -// app.ui.settings.addSetting(this.monitorRAMElement); -// app.ui.settings.addSetting(this.monitorCPUElement); -// -// void this.getHDDsFromServer().then((data: string[]): void => { -// // @ts-ignore -// this.settingsHDD.data = data; -// app.ui.settings.addSetting(this.settingsHDD); -// }); -// app.ui.settings.addSetting(this.monitorHDDElement); -// -// void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { -// let moreThanOneGPU = false; -// if (gpus.length > 1) { -// moreThanOneGPU = true; -// } -// -// gpus?.forEach(({name, index}) => { -// -// this.createSettingsGPUTemp(name, index, moreThanOneGPU); -// this.createSettingsGPUVRAM(name, index, moreThanOneGPU); -// this.createSettingsGPUUsage(name, index, moreThanOneGPU); -// -// }); -// }); -// }; -// -// updateDisplay = (): void => { -// console.log('updateDisplay'); -// const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); -// -// if (newMenu !== this.newMenu) { -// this.newMenu = newMenu; -// -// if (this.monitorUI) { -// this.monitorUI.newMenu = this.newMenu; -// } -// -// if (this.newMenu === NewMenuOptions.Disabled) { -// this.setup(); -// } -// } -// }; -// -// updateServer = async(data: TStatsSettings): Promise => { -// const resp = await api.fetchApi('/crystools/monitor', { -// method: 'PATCH', -// body: JSON.stringify(data), -// cache: 'no-store', -// }); -// if (resp.status === 200) { -// return await resp.text(); -// } -// throw new Error(resp.statusText); -// }; -// -// updateServerGPU = async(index: number, data: TGpuSettings): Promise => { -// const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { -// method: 'PATCH', -// body: JSON.stringify(data), -// cache: 'no-store', -// }); -// if (resp.status === 200) { -// return await resp.text(); -// } -// throw new Error(resp.statusText); -// }; -// -// getHDDsFromServer = async(): Promise => { -// return this.getDataFromServer('HDD'); -// }; -// -// getGPUsFromServer = async(): Promise => { -// return this.getDataFromServer('GPU'); -// }; -// -// getDataFromServer = async (what: string): Promise => { -// const resp = await api.fetchApi(`/crystools/monitor/${what}`, { -// method: 'GET', -// cache: 'no-store', -// }); -// if (resp.status === 200) { -// return await resp.json(); -// } -// throw new Error(resp.statusText); -// }; -// -// setup(): void { -// console.log('setup'); -// if (this.monitorUI) { -// return; -// } -// console.log('setup nuevo'); -// const currentRate = -// parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); -// -// this.monitorUI = new MonitorUI( -// this.monitorCPUElement, -// this.monitorRAMElement, -// this.monitorHDDElement, -// this.monitorGPUSettings, -// this.monitorVRAMSettings, -// this.monitorTemperatureSettings, -// currentRate, -// ); -// -// this.registerListeners(); -// } -// -// registerListeners = (): void => { -// api.addEventListener('crystools.monitor', (event: CustomEvent) => { -// if (event?.detail === undefined) { -// return; -// } -// this.monitorUI.updateAllMonitors(event.detail); -// }, false); -// }; -// } -// -// const crystoolsMonitor = new CrystoolsMonitor(); -// app.registerExtension({ -// name: crystoolsMonitor.idExtensionName, -// setup: crystoolsMonitor.setup.bind(crystoolsMonitor), -// }); +import { app, api } from './comfy/index.js'; +import { commonPrefix } from './common.js'; +import { MonitorVerticalUI } from './monitorVerticalUI.js'; +import { Colors } from './styles.js'; +import { convertNumberToPascalCase } from './utils.js'; +import { NewMenuOptions } from './progressBarUIBase.js'; + +class CrystoolsMonitor { + idExtensionName = 'Crystools.monitor'; + menuPrefix = commonPrefix; + newMenu: NewMenuOptions = NewMenuOptions.Disabled; + + settingsRate: TMonitorSettings; + monitorCPUElement: TMonitorSettings; + monitorRAMElement: TMonitorSettings; + monitorHDDElement: TMonitorSettings; + settingsHDD: TMonitorSettings; + monitorGPUSettings: TMonitorSettings[] = []; + monitorVRAMSettings: TMonitorSettings[] = []; + monitorTemperatureSettings: TMonitorSettings[] = []; + + monitorVerticalUI: MonitorVerticalUI; + + constructor() { + window.addEventListener('resize', this.updateDisplay); + } + + createSettingsRate = (): void => { + this.settingsRate = { + id: 'Crystools.RefreshRate', + name: 'Refresh per second', + category: ['Crystools', this.menuPrefix + ' Refresh Rate'], + tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', + type: 'slider', + attrs: { + min: 0, + max: 2, + step: 0.25, + }, + defaultValue: .5, + // @ts-ignore + onChange: async(value: string): Promise => { + let valueNumber: number; + + try { + valueNumber = parseFloat(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } catch (error) { + console.error(error); + return; + } + try { + await this.updateServer({rate: valueNumber}); + } catch (error) { + console.error(error); + return; + } + + if (valueNumber === 0) { + this.monitorVerticalUI.updateDisplay({ + cpu_utilization: 0, + device: 'cpu', + + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }); + } + + this.monitorVerticalUI?.updateAllAnimationDuration(valueNumber); + }, + }; + }; + + createSettingsCPU = (): void => { + // CPU Variables + this.monitorCPUElement = { + id: 'Crystools.ShowCpu', + name: 'CPU Usage', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Cpu'], + type: 'boolean', + label: 'CPU', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.CPU, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorVerticalUI?.updateWidget(this.monitorCPUElement); + await this.updateServer({switchCPU: value}); + }, + }; + }; + + createSettingsRAM = (): void => { + // RAM Variables + this.monitorRAMElement = { + id: 'Crystools.ShowRam', + name: 'RAM Used', + category: ['Crystools', this.menuPrefix + ' Hardware', 'Ram'], + type: 'boolean', + label: 'RAM', + symbol: '%', + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.RAM, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorVerticalUI?.updateWidget(this.monitorRAMElement); + await this.updateServer({switchRAM: value}); + }, + }; + }; + + createSettingsGPUUsage = (name: string, index: number, moreThanOneGPU: boolean): void => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + + let label = 'GPU '; + label += moreThanOneGPU ? index : ''; + + const monitorGPUNElement: TMonitorSettings = { + id: 'Crystools.ShowGpuUsage' + convertNumberToPascalCase(index), + name: ' Usage', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Usage'], + type: 'boolean', + label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.GPU, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorVerticalUI?.updateWidget(monitorGPUNElement); + void await this.updateServerGPU(index, {utilization: value}); + }, + }; + + this.monitorGPUSettings[index] = monitorGPUNElement; + app.ui.settings.addSetting(this.monitorGPUSettings[index]); + this.monitorVerticalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); + }; + + createSettingsGPUVRAM = (name: string, index: number, moreThanOneGPU: boolean): void => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + + let label = 'VRAM '; + label += moreThanOneGPU ? index : ''; + + // GPU VRAM Variables + const monitorVRAMNElement: TMonitorSettings = { + id: 'Crystools.ShowGpuVram' + convertNumberToPascalCase(index), + name: 'VRAM', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'VRAM'], + type: 'boolean', + label: label, + symbol: '%', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.VRAM, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorVerticalUI?.updateWidget(monitorVRAMNElement); + void await this.updateServerGPU(index, {vram: value}); + }, + }; + + this.monitorVRAMSettings[index] = monitorVRAMNElement; + app.ui.settings.addSetting(this.monitorVRAMSettings[index]); + this.monitorVerticalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); + }; + + createSettingsGPUTemp = (name: string, index: number, moreThanOneGPU: boolean): void => { + if (name === undefined || index === undefined) { + console.warn('getGPUsFromServer: name or index undefined', name, index); + return; + } + + let label = 'Temp '; + label += moreThanOneGPU ? index : ''; + + // GPU Temperature Variables + const monitorTemperatureNElement: TMonitorSettings = { + id: 'Crystools.ShowGpuTemperature' + convertNumberToPascalCase(index), + name: 'Temperature', + category: ['Crystools', `${this.menuPrefix} Show GPU [${index}] ${name}`, 'Temperature'], + type: 'boolean', + label: label, + symbol: '°', + title: `${index}: ${name}`, + defaultValue: true, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.TEMP_START, + cssColorFinal: Colors.TEMP_END, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorVerticalUI?.updateWidget(monitorTemperatureNElement); + void await this.updateServerGPU(index, {temperature: value}); + }, + }; + + this.monitorTemperatureSettings[index] = monitorTemperatureNElement; + app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); + this.monitorVerticalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); + }; + + createSettingsHDD = (): void => { + // HDD Variables + this.monitorHDDElement = { + id: 'Crystools.ShowHdd', + name: 'Show HDD Used', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Show'], + type: 'boolean', + label: 'HDD', + symbol: '%', + // tooltip: 'See Partition to show (HDD)', + defaultValue: false, + htmlMonitorRef: undefined, + htmlMonitorSliderRef: undefined, + htmlMonitorLabelRef: undefined, + cssColor: Colors.DISK, + // @ts-ignore + onChange: async(value: boolean): Promise => { + this.monitorVerticalUI?.updateWidget(this.monitorHDDElement); + await this.updateServer({switchHDD: value}); + }, + }; + + this.settingsHDD = { + id: 'Crystools.WhichHdd', + name: 'Partition to show', + category: ['Crystools', this.menuPrefix + ' Show Hard Disk', 'Which'], + type: 'combo', + defaultValue: '/', + data: [], + // @ts-ignore bad definition from comfyUI: `options?: undefined;`?? + options: (value: string): any => { + const which = app.ui.settings.getSettingValue(this.settingsHDD.id, this.settingsHDD.defaultValue); + return this.settingsHDD.data.map((m: any) => ({ + value: m, + text: m, + selected: !value ? m === which : m === value, + })); + }, + // @ts-ignore + onChange: async(value: string): Promise => { + await this.updateServer({whichHDD: value}); + }, + }; + }; + + createSettings = (): void => { + app.ui.settings.addSetting(this.settingsRate); + app.ui.settings.addSetting(this.monitorRAMElement); + app.ui.settings.addSetting(this.monitorCPUElement); + + void this.getHDDsFromServer().then((data: string[]): void => { + this.settingsHDD.data = data; + app.ui.settings.addSetting(this.settingsHDD); + }); + app.ui.settings.addSetting(this.monitorHDDElement); + + void this.getGPUsFromServer().then((gpus: TGpuName[]): void => { + let moreThanOneGPU = false; + if (gpus.length > 1) { + moreThanOneGPU = true; + } + + gpus?.forEach(({name, index}) => { + this.createSettingsGPUTemp(name, index, moreThanOneGPU); + this.createSettingsGPUVRAM(name, index, moreThanOneGPU); + this.createSettingsGPUUsage(name, index, moreThanOneGPU); + }); + + this.monitorVerticalUI.orderMonitors(); + }); + }; + + updateDisplay = (): void => { + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + + this.monitorVerticalUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); + if (this.monitorVerticalUI.showSection) { + this.setup(); + } + } + + }; + + updateServer = async(data: TStatsSettings): Promise => { + const resp = await api.fetchApi('/crystools/monitor', { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + }; + + updateServerGPU = async(index: number, data: TGpuSettings): Promise => { + const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, { + method: 'PATCH', + body: JSON.stringify(data), + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.text(); + } + throw new Error(resp.statusText); + }; + + getHDDsFromServer = async(): Promise => { + return this.getDataFromServer('HDD'); + }; + + getGPUsFromServer = async(): Promise => { + return this.getDataFromServer('GPU'); + }; + + getDataFromServer = async (what: string): Promise => { + const resp = await api.fetchApi(`/crystools/monitor/${what}`, { + method: 'GET', + cache: 'no-store', + }); + if (resp.status === 200) { + return await resp.json(); + } + throw new Error(resp.statusText); + }; + + setup = (): void => { + if (this.monitorVerticalUI) { + // this.monitorUIOld.render(0); + return; + } + + this.createSettingsRate(); + this.createSettingsCPU(); + this.createSettingsRAM(); + this.createSettingsHDD(); + this.createSettings(); + + const currentRate = + parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); + + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + this.monitorVerticalUI = new MonitorVerticalUI( + this.monitorCPUElement, + this.monitorRAMElement, + this.monitorHDDElement, + this.monitorGPUSettings, + this.monitorVRAMSettings, + this.monitorTemperatureSettings, + currentRate, + (this.newMenu === NewMenuOptions.Disabled), + ); + + this.updateDisplay(); + this.registerListeners(); + }; + + registerListeners = (): void => { + api.addEventListener('crystools.monitor', (event: CustomEvent) => { + if (event?.detail === undefined) { + return; + } + this.monitorVerticalUI.updateDisplay(event.detail); + }, false); + }; +} + +const crystoolsMonitor = new CrystoolsMonitor(); +app.registerExtension({ + name: crystoolsMonitor.idExtensionName, + setup: crystoolsMonitor.setup, +}); diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts deleted file mode 100644 index e69de29..0000000 diff --git a/web/monitorUI.js b/web/monitorUI.js deleted file mode 100644 index 3918c74..0000000 --- a/web/monitorUI.js +++ /dev/null @@ -1 +0,0 @@ -"use strict"; diff --git a/web/monitorUI.ts b/web/monitorUI.ts deleted file mode 100644 index 90e9e0e..0000000 --- a/web/monitorUI.ts +++ /dev/null @@ -1,240 +0,0 @@ -// import { app } from './comfy/index.js'; -// import { ProgressBarUIBase } from './progressBarUIBase.js'; -// -// export class MonitorUI extends ProgressBarUIBase { -// private htmlContainer: HTMLDivElement; -// private htmlIdCrystoolsRoot = 'crystools-root'; -// private htmlClassParentElement = 'comfyui-menu-push'; -// -// constructor( -// private monitorCPUElement: TMonitorSettings, -// private monitorRAMElement: TMonitorSettings, -// private monitorHDDElement: TMonitorSettings, -// private monitorGPUSettings: TMonitorSettings[], -// private monitorVRAMSettings: TMonitorSettings[], -// private monitorTemperatureSettings: TMonitorSettings[], -// private currentRate: number -// ) { -// super(); -// this.createRootOldMenu(); -// this.createDOM(); -// console.log('MonitorUI created', this.newMenu); -// } -// -// override createDOM = (): void => { -// this.createDOMOldMenu(); -// this.createDOMNewMenu(); -// }; -// -// createDOMNewMenu = (): void => { -// this.htmlContainer = document.createElement('div'); -// this.htmlContainer.setAttribute('id', this.htmlIdCrystoolsRoot); -// -// // the best parentElement: -// const parentElement = document.getElementsByClassName(this.htmlClassParentElement)[0]; -// parentElement?.insertAdjacentElement('afterend', this.htmlContainer); -// -// this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); -// // this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); -// }; -// -// createDOMOldMenu = (): void => { -// this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); -// this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); -// -// // gpu0 > gpu1 > vram0 > vram1 -// // this.monitorGPUSettings.forEach((monitorSettings) => { -// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); -// // }); -// // this.monitorVRAMSettings.forEach((monitorSettings) => { -// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); -// // }); -// // this.monitorTemperatureSettings.forEach((monitorSettings) => { -// // monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings)); -// // }); -// -// // gpu0 > vram0 > gpu1 > vram1 -// this.monitorGPUSettings.forEach((_monitorSettings, index) => { -// this.monitorGPUSettings[index] && -// this.htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index])); -// this.monitorVRAMSettings[index] && -// this.htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index])); -// this.monitorTemperatureSettings[index] && -// this.htmlContainer.append(this.createMonitor(this.monitorTemperatureSettings[index])); -// }); -// -// this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); -// -// this.updateAllAnimationDuration(this.currentRate); -// this.updateAllWidget(); -// }; -// -// -// refreshDisplay = (): void => { -// // console.log('refreshDisplay'); -// this.updateAllWidget(); -// }; -// -// -// updateAllWidget = (): void => { -// this.updateWidget(this.monitorCPUElement); -// this.updateWidget(this.monitorRAMElement); -// this.updateWidget(this.monitorHDDElement); -// -// this.monitorGPUSettings.forEach((monitorSettings) => { -// monitorSettings && this.updateWidget(monitorSettings); -// }); -// this.monitorVRAMSettings.forEach((monitorSettings) => { -// monitorSettings && this.updateWidget(monitorSettings); -// }); -// this.monitorTemperatureSettings.forEach((monitorSettings) => { -// monitorSettings && this.updateWidget(monitorSettings); -// }); -// }; -// -// /** -// * for the settings menu -// * @param monitorSettings -// */ -// updateWidget = (monitorSettings: TMonitorSettings): void => { -// const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); -// if (monitorSettings.htmlMonitorRef) { -// monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; -// } -// }; -// -// updateAllMonitors = (data: TStatsData): void => { -// // console.log('updateAllMonitors', data); -// this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); -// this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); -// this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); -// -// if (data.gpus === undefined || data.gpus.length === 0) { -// console.warn('UpdateAllMonitors: no GPU data'); -// return; -// } -// -// this.monitorGPUSettings.forEach((monitorSettings, index) => { -// if (data.gpus[index]) { -// const gpu = data.gpus[index]; -// if (gpu === undefined) { -// // console.error('UpdateAllMonitors: no GPU data for index', index); -// return; -// } -// -// this.updateMonitor(monitorSettings, gpu.gpu_utilization); -// } else { -// // console.error('UpdateAllMonitors: no GPU data for index', index); -// } -// }); -// -// this.monitorVRAMSettings.forEach((monitorSettings, index) => { -// if (data.gpus[index]) { -// const gpu = data.gpus[index]; -// if (gpu === undefined) { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// return; -// } -// -// this.updateMonitor(monitorSettings, gpu.vram_used_percent); -// } else { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// } -// }); -// -// this.monitorTemperatureSettings.forEach((monitorSettings, index) => { -// if (data.gpus[index]) { -// const gpu = data.gpus[index]; -// if (gpu === undefined) { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// return; -// } -// -// this.updateMonitor(monitorSettings, gpu.gpu_temperature); -// if(monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef){ -// monitorSettings.htmlMonitorSliderRef.style.backgroundColor = -// `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; -// } -// } else { -// // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); -// } -// }); -// }; -// -// updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { -// if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { -// return; -// } -// -// monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; -// monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; -// }; -// -// updateAllAnimationDuration = (value: number): void => { -// this.updatedAnimationDuration(this.monitorCPUElement, value); -// this.updatedAnimationDuration(this.monitorRAMElement, value); -// this.updatedAnimationDuration(this.monitorHDDElement, value); -// this.monitorGPUSettings.forEach((monitorSettings) => { -// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); -// }); -// this.monitorVRAMSettings.forEach((monitorSettings) => { -// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); -// }); -// this.monitorTemperatureSettings.forEach((monitorSettings) => { -// monitorSettings && this.updatedAnimationDuration(monitorSettings, value); -// }); -// }; -// -// updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { -// const slider = monitorSettings.htmlMonitorSliderRef; -// if (!slider) { -// return; -// } -// -// slider.style.transition = `width ${value.toFixed(1)}s`; -// }; -// -// -// createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { -// if (!monitorSettings) { -// // just for typescript -// return document.createElement('div'); -// } -// -// const htmlMain = document.createElement('div'); -// htmlMain.classList.add(monitorSettings.id); -// htmlMain.classList.add('crystools-monitor'); -// monitorSettings.htmlMonitorRef = htmlMain; -// -// if (monitorSettings.title) { -// htmlMain.title = monitorSettings.title; -// } -// -// const htmlMonitorText = document.createElement('div'); -// htmlMonitorText.classList.add('crystools-text'); -// htmlMonitorText.innerHTML = monitorSettings.label; -// htmlMain.append(htmlMonitorText); -// -// const htmlMonitorContent = document.createElement('div'); -// htmlMonitorContent.classList.add('crystools-content'); -// htmlMain.append(htmlMonitorContent); -// -// const htmlMonitorSlider = document.createElement('div'); -// htmlMonitorSlider.classList.add('crystools-slider'); -// if(monitorSettings.cssColorFinal){ -// htmlMonitorSlider.style.backgroundColor = -// `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; -// } else { -// htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; -// } -// monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; -// htmlMonitorContent.append(htmlMonitorSlider); -// -// const htmlMonitorLabel = document.createElement('div'); -// htmlMonitorLabel.classList.add('crystools-label'); -// monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; -// htmlMonitorContent.append(htmlMonitorLabel); -// htmlMonitorLabel.innerHTML = '0%'; -// return monitorSettings.htmlMonitorRef; -// }; -// } diff --git a/web/monitorVerticalUI.d.ts b/web/monitorVerticalUI.d.ts new file mode 100644 index 0000000..ec565b7 --- /dev/null +++ b/web/monitorVerticalUI.d.ts @@ -0,0 +1,22 @@ +import { ProgressBarUIBase } from './progressBarUIBase.js'; +export declare class MonitorVerticalUI extends ProgressBarUIBase { + private monitorCPUElement; + private monitorRAMElement; + private monitorHDDElement; + private monitorGPUSettings; + private monitorVRAMSettings; + private monitorTemperatureSettings; + private currentRate; + lastMonitor: number; + constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number, showSection: boolean); + createDOM: () => void; + createDOMGPUMonitor: (monitorSettings?: TMonitorSettings) => void; + orderMonitors: () => void; + updateAllWidget: () => void; + updateWidget: (monitorSettings: TMonitorSettings) => void; + updateDisplay: (data: TStatsData) => void; + updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; + updateAllAnimationDuration: (value: number) => void; + updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; + createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; +} diff --git a/web/monitorVerticalUI.js b/web/monitorVerticalUI.js new file mode 100644 index 0000000..48b903c --- /dev/null +++ b/web/monitorVerticalUI.js @@ -0,0 +1,273 @@ +import { app } from './comfy/index.js'; +import { ProgressBarUIBase } from './progressBarUIBase.js'; +export class MonitorVerticalUI extends ProgressBarUIBase { + constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate, showSection) { + super('queue-button', 'crystools-root-old', showSection); + Object.defineProperty(this, "monitorCPUElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorCPUElement + }); + Object.defineProperty(this, "monitorRAMElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorRAMElement + }); + Object.defineProperty(this, "monitorHDDElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorHDDElement + }); + Object.defineProperty(this, "monitorGPUSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorGPUSettings + }); + Object.defineProperty(this, "monitorVRAMSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorVRAMSettings + }); + Object.defineProperty(this, "monitorTemperatureSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorTemperatureSettings + }); + Object.defineProperty(this, "currentRate", { + enumerable: true, + configurable: true, + writable: true, + value: currentRate + }); + Object.defineProperty(this, "lastMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: 1 + }); + Object.defineProperty(this, "createDOM", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.htmlContainer.style.order = '2'; + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + } + }); + Object.defineProperty(this, "createDOMGPUMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + if (!monitorSettings) { + return; + } + this.htmlContainer.append(this.createMonitor(monitorSettings)); + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + } + }); + Object.defineProperty(this, "orderMonitors", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + try { + this.monitorCPUElement.htmlMonitorRef.style.order = '' + this.lastMonitor++; + this.monitorRAMElement.htmlMonitorRef.style.order = '' + this.lastMonitor++; + this.monitorGPUSettings.forEach((_monitorSettings, index) => { + this.monitorGPUSettings[index].htmlMonitorRef.style.order = '' + this.lastMonitor++; + this.monitorVRAMSettings[index].htmlMonitorRef.style.order = '' + this.lastMonitor++; + this.monitorTemperatureSettings[index].htmlMonitorRef.style.order = '' + this.lastMonitor++; + }); + this.monitorHDDElement.htmlMonitorRef.style.order = '' + this.lastMonitor++; + } + catch (error) { + console.error('orderMonitors', error); + } + } + }); + Object.defineProperty(this, "updateAllWidget", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + } + }); + Object.defineProperty(this, "updateWidget", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + } + }); + Object.defineProperty(this, "updateDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: (data) => { + this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + if (data.gpus === undefined || data.gpus.length === 0) { + console.warn('UpdateAllMonitors: no GPU data'); + return; + } + this.monitorGPUSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.gpu_utilization); + } + else { + } + }); + this.monitorVRAMSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.vram_used_percent); + } + else { + } + }); + this.monitorTemperatureSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + return; + } + this.updateMonitor(monitorSettings, gpu.gpu_temperature); + if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { + monitorSettings.htmlMonitorSliderRef.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; + } + } + else { + } + }); + } + }); + Object.defineProperty(this, "updateMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, percent) => { + if (!this.showSection) { + return; + } + if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { + return; + } + if (percent < 0) { + return; + } + monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; + monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; + } + }); + Object.defineProperty(this, "updateAllAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + this.updatedAnimationDuration(this.monitorCPUElement, value); + this.updatedAnimationDuration(this.monitorRAMElement, value); + this.updatedAnimationDuration(this.monitorHDDElement, value); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + } + }); + Object.defineProperty(this, "updatedAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, value) => { + const slider = monitorSettings.htmlMonitorSliderRef; + if (!slider) { + return; + } + slider.style.transition = `width ${value.toFixed(1)}s`; + } + }); + Object.defineProperty(this, "createMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + if (!monitorSettings) { + return document.createElement('div'); + } + const htmlMain = document.createElement('div'); + htmlMain.classList.add(monitorSettings.id); + htmlMain.classList.add('crystools-monitor'); + monitorSettings.htmlMonitorRef = htmlMain; + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.classList.add('crystools-text'); + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.classList.add('crystools-content'); + htmlMain.append(htmlMonitorContent); + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.classList.add('crystools-slider'); + if (monitorSettings.cssColorFinal) { + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } + else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.classList.add('crystools-label'); + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + htmlMonitorLabel.innerHTML = '0%'; + return monitorSettings.htmlMonitorRef; + } + }); + this.createDOM(); + } +} diff --git a/web/monitorVerticalUI.ts b/web/monitorVerticalUI.ts new file mode 100644 index 0000000..be587fd --- /dev/null +++ b/web/monitorVerticalUI.ts @@ -0,0 +1,232 @@ +import { app } from './comfy/index.js'; +import { ProgressBarUIBase } from './progressBarUIBase.js'; + +export class MonitorVerticalUI extends ProgressBarUIBase { + lastMonitor = 1; // just for order on monitors section + + constructor( + private monitorCPUElement: TMonitorSettings, + private monitorRAMElement: TMonitorSettings, + private monitorHDDElement: TMonitorSettings, + private monitorGPUSettings: TMonitorSettings[], + private monitorVRAMSettings: TMonitorSettings[], + private monitorTemperatureSettings: TMonitorSettings[], + private currentRate: number, + showSection: boolean, + ) { + super('queue-button', 'crystools-root-old', showSection); + this.createDOM(); + } + + createDOM = (): void => { + this.htmlContainer.style.order = '2'; + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + }; + + createDOMGPUMonitor = (monitorSettings?: TMonitorSettings): void => { + if (!monitorSettings) { + return; + } + + this.htmlContainer.append(this.createMonitor(monitorSettings)); + this.updateAllAnimationDuration(this.currentRate); + this.updateAllWidget(); + }; + + orderMonitors = (): void => { + try { + // @ts-ignore + this.monitorCPUElement.htmlMonitorRef.style.order = '' + this.lastMonitor++; + // @ts-ignore + this.monitorRAMElement.htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // @ts-ignore + this.monitorGPUSettings.forEach((_monitorSettings, index) => { + // @ts-ignore + this.monitorGPUSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // @ts-ignore + this.monitorVRAMSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // @ts-ignore + this.monitorTemperatureSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; + }); + // @ts-ignore + this.monitorHDDElement.htmlMonitorRef.style.order = ''+ this.lastMonitor++; + } catch (error) { + console.error('orderMonitors', error); + } + }; + + updateAllWidget = (): void => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + }; + + /** + * for the settings menu + * @param monitorSettings + */ + updateWidget = (monitorSettings: TMonitorSettings): void => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + }; + + updateDisplay = (data: TStatsData): void => { + this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + + if (data.gpus === undefined || data.gpus.length === 0) { + console.warn('UpdateAllMonitors: no GPU data'); + return; + } + + this.monitorGPUSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.gpu_utilization); + } else { + // console.error('UpdateAllMonitors: no GPU data for index', index); + } + }); + + this.monitorVRAMSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.vram_used_percent); + } else { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + } + }); + + this.monitorTemperatureSettings.forEach((monitorSettings, index) => { + if (data.gpus[index]) { + const gpu = data.gpus[index]; + if (gpu === undefined) { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + return; + } + + this.updateMonitor(monitorSettings, gpu.gpu_temperature); + if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { + monitorSettings.htmlMonitorSliderRef.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; + } + } else { + // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + } + }); + }; + + updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { + if (!this.showSection) { + return; + } + + if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { + return; + } + + if (percent < 0) { + return; + } + + // console.log('updateMonitor', monitorSettings.id, percent); + + monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; + monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; + }; + + updateAllAnimationDuration = (value: number): void => { + this.updatedAnimationDuration(this.monitorCPUElement, value); + this.updatedAnimationDuration(this.monitorRAMElement, value); + this.updatedAnimationDuration(this.monitorHDDElement, value); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + }); + }; + + updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { + const slider = monitorSettings.htmlMonitorSliderRef; + if (!slider) { + return; + } + + slider.style.transition = `width ${value.toFixed(1)}s`; + }; + + createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { + if (!monitorSettings) { + // just for typescript + return document.createElement('div'); + } + + const htmlMain = document.createElement('div'); + htmlMain.classList.add(monitorSettings.id); + htmlMain.classList.add('crystools-monitor'); + + monitorSettings.htmlMonitorRef = htmlMain; + + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.classList.add('crystools-text'); + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.classList.add('crystools-content'); + htmlMain.append(htmlMonitorContent); + + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.classList.add('crystools-slider'); + if (monitorSettings.cssColorFinal) { + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.classList.add('crystools-label'); + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + htmlMonitorLabel.innerHTML = '0%'; + return monitorSettings.htmlMonitorRef; + }; +} diff --git a/web/progressBar.js b/web/progressBar.js index d6533d9..dc14a7f 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -76,7 +76,7 @@ class CrystoolsProgressBar { tooltip: 'This apply only on old menu', type: 'boolean', defaultValue: this.defaultShowStatus, - onChange: this.progressBarUI.render, + onChange: this.progressBarUI.showProgressBar, }); } }); @@ -85,22 +85,34 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: () => { - if (!this.progressBarUI.show) { - return; - } const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; - if (this.newMenu === NewMenuOptions.Disabled) { + this.progressBarUI.showSection = (this.newMenu === NewMenuOptions.Disabled); + if (this.progressBarUI.showSection) { this.setup(); } - else { - this.progressBarUI.show = false; - } } this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } }); + Object.defineProperty(this, "setup", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + if (this.progressBarUI) { + this.progressBarUI + .showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); + return; + } + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + this.progressBarUI = new ProgressBarUI((this.newMenu === NewMenuOptions.Disabled), this.centerNode); + this.createSettings(); + this.updateDisplay(); + this.registerListeners(); + } + }); Object.defineProperty(this, "registerListeners", { enumerable: true, configurable: true, @@ -156,22 +168,11 @@ class CrystoolsProgressBar { app.canvas.centerOnNode(node); } }); - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - } - setup() { - if (this.progressBarUI) { - this.progressBarUI.render(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); - return; - } - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - this.progressBarUI = new ProgressBarUI(this.centerNode, (this.newMenu === NewMenuOptions.Disabled)); - this.createSettings(); - this.updateDisplay(); - this.registerListeners(); + window.addEventListener('resize', this.updateDisplay); } } const crystoolsProgressBar = new CrystoolsProgressBar(); app.registerExtension({ name: crystoolsProgressBar.idExtensionName, - setup: crystoolsProgressBar.setup.bind(crystoolsProgressBar), + setup: crystoolsProgressBar.setup, }); diff --git a/web/progressBar.ts b/web/progressBar.ts index f00f459..ed2d274 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -18,7 +18,7 @@ class CrystoolsProgressBar { progressBarUI: ProgressBarUI; constructor() { - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + window.addEventListener('resize', this.updateDisplay); } // not on setup because this affect the order on settings, I prefer to options at first @@ -30,24 +30,19 @@ class CrystoolsProgressBar { tooltip: 'This apply only on old menu', type: 'boolean', defaultValue: this.defaultShowStatus, - onChange: this.progressBarUI.render, + onChange: this.progressBarUI.showProgressBar, }); }; updateDisplay = (): void => { - if(!this.progressBarUI.show){ - return; - } - const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; - if (this.newMenu === NewMenuOptions.Disabled) { + this.progressBarUI.showSection = (this.newMenu === NewMenuOptions.Disabled); + if (this.progressBarUI.showSection) { this.setup(); - } else { - this.progressBarUI.show = false; } } @@ -55,19 +50,20 @@ class CrystoolsProgressBar { }; // automatically called by ComfyUI - setup(): void { + setup = (): void => { if (this.progressBarUI) { - this.progressBarUI.render(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); + this.progressBarUI + .showProgressBar(app.ui.settings.getSettingValue(this.idShowProgressBar, this.defaultShowStatus)); return; } this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - this.progressBarUI = new ProgressBarUI(this.centerNode, (this.newMenu === NewMenuOptions.Disabled)); + this.progressBarUI = new ProgressBarUI((this.newMenu === NewMenuOptions.Disabled), this.centerNode); this.createSettings(); this.updateDisplay(); this.registerListeners(); - } + }; registerListeners = (): void => { api.addEventListener('status', ({detail}: any) => { @@ -130,5 +126,5 @@ class CrystoolsProgressBar { const crystoolsProgressBar = new CrystoolsProgressBar(); app.registerExtension({ name: crystoolsProgressBar.idExtensionName, - setup: crystoolsProgressBar.setup.bind(crystoolsProgressBar), + setup: crystoolsProgressBar.setup, }); diff --git a/web/progressBarUI.d.ts b/web/progressBarUI.d.ts index 01a6c39..8d2755f 100644 --- a/web/progressBarUI.d.ts +++ b/web/progressBarUI.d.ts @@ -6,8 +6,9 @@ export declare class ProgressBarUI extends ProgressBarUIBase { currentStatus: EStatus; timeStart: number; currentProgress: number; - constructor(centerNode: () => void, show: boolean); + progressBar: boolean; + constructor(showSection: boolean, centerNode: () => void); createDOM: () => void; updateDisplay: (currentStatus: EStatus, timeStart: number, currentProgress: number) => void; - private refreshDisplay; + showProgressBar: (value: boolean) => void; } diff --git a/web/progressBarUI.js b/web/progressBarUI.js index 19d7d4a..7772dfb 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,7 +1,7 @@ import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export class ProgressBarUI extends ProgressBarUIBase { - constructor(centerNode, show) { - super('queue-button', 'crystools-root-old', show); + constructor(showSection, centerNode) { + super('queue-button', 'crystools-root-old', showSection); Object.defineProperty(this, "centerNode", { enumerable: true, configurable: true, @@ -38,6 +38,12 @@ export class ProgressBarUI extends ProgressBarUIBase { writable: true, value: void 0 }); + Object.defineProperty(this, "progressBar", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); Object.defineProperty(this, "createDOM", { enumerable: true, configurable: true, @@ -67,7 +73,10 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: (currentStatus, timeStart, currentProgress) => { - if (!this.show) { + if (!this.showSection) { + return; + } + if (!this.progressBar) { return; } if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { @@ -96,17 +105,15 @@ export class ProgressBarUI extends ProgressBarUIBase { } } }); - Object.defineProperty(this, "refreshDisplay", { + Object.defineProperty(this, "showProgressBar", { enumerable: true, configurable: true, writable: true, - value: () => { - if (this.show) { - this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); - } + value: (value) => { + this.progressBar = value; + this.htmlContainer.style.display = this.progressBar ? 'block' : 'none'; } }); - window.addEventListener('resize', this.refreshDisplay); this.createDOM(); } } diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index ff39edd..07be192 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -1,18 +1,18 @@ import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; -export class ProgressBarUI extends ProgressBarUIBase{ +export class ProgressBarUI extends ProgressBarUIBase { htmlProgressSliderRef: HTMLDivElement; htmlProgressLabelRef: HTMLDivElement; currentStatus: EStatus; timeStart: number; currentProgress: number; + progressBar: boolean; - constructor ( + constructor( + showSection: boolean, private centerNode: () => void, - show: boolean, ) { - super('queue-button', 'crystools-root-old', show); - window.addEventListener('resize', this.refreshDisplay); + super('queue-button', 'crystools-root-old', showSection); this.createDOM(); } @@ -41,19 +41,25 @@ export class ProgressBarUI extends ProgressBarUIBase{ // eslint-disable-next-line complexity updateDisplay = (currentStatus: EStatus, timeStart: number, currentProgress: number): void => { - if (!this.show) { + if (!this.showSection) { return; } + + if (!this.progressBar) { + return; + } + if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { console.error('htmlProgressLabelRef or htmlProgressSliderRef is undefined'); return; } + // console.log('only if showSection and progressBar', timeStart, currentProgress); + this.currentStatus = currentStatus; this.timeStart = timeStart; this.currentProgress = currentProgress; - if (currentStatus === EStatus.executed) { // finished this.htmlProgressLabelRef.innerHTML = 'cached'; @@ -78,10 +84,9 @@ export class ProgressBarUI extends ProgressBarUIBase{ }; - // not data only display - private refreshDisplay = (): void => { - if (this.show) { - this.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); - } + // remember it can't have more parameters because it is used on settings automatically + public showProgressBar = (value: boolean): void => { + this.progressBar = value; + this.htmlContainer.style.display = this.progressBar ? 'block' : 'none'; }; } diff --git a/web/progressBarUIBase.d.ts b/web/progressBarUIBase.d.ts index 2c7ae28..65a26a6 100644 --- a/web/progressBarUIBase.d.ts +++ b/web/progressBarUIBase.d.ts @@ -11,12 +11,11 @@ export declare enum NewMenuOptions { export declare abstract class ProgressBarUIBase { parentId: string; rootId: string; - show: boolean; + showSection: boolean; protected htmlContainer: HTMLDivElement; protected htmlClassMonitor: string; - protected constructor(parentId: string, rootId: string, show: boolean); + protected constructor(parentId: string, rootId: string, showSection: boolean); private createRoot; - render: (value: boolean) => void; + showFullSection(value: boolean): void; abstract createDOM(): void; - abstract updateDisplay(currentStatus: EStatus, timeStart: number, currentProgress: number): void; } diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js index 8d51e1d..6b0e4cf 100644 --- a/web/progressBarUIBase.js +++ b/web/progressBarUIBase.js @@ -11,7 +11,7 @@ export var NewMenuOptions; NewMenuOptions["Bottom"] = "Bottom"; })(NewMenuOptions || (NewMenuOptions = {})); export class ProgressBarUIBase { - constructor(parentId, rootId, show) { + constructor(parentId, rootId, showSection) { Object.defineProperty(this, "parentId", { enumerable: true, configurable: true, @@ -24,11 +24,11 @@ export class ProgressBarUIBase { writable: true, value: rootId }); - Object.defineProperty(this, "show", { + Object.defineProperty(this, "showSection", { enumerable: true, configurable: true, writable: true, - value: show + value: showSection }); Object.defineProperty(this, "htmlContainer", { enumerable: true, @@ -59,15 +59,11 @@ export class ProgressBarUIBase { ctoolsRoot.append(this.htmlContainer); } }); - Object.defineProperty(this, "render", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - this.show = value; - this.htmlContainer.style.display = this.show ? 'block' : 'none'; - } - }); this.createRoot(); + this.showFullSection(this.showSection); + } + showFullSection(value) { + this.showSection = value; + this.htmlContainer.style.display = value ? 'flex' : 'none'; } } diff --git a/web/progressBarUIBase.ts b/web/progressBarUIBase.ts index 253f3e9..db2cf30 100644 --- a/web/progressBarUIBase.ts +++ b/web/progressBarUIBase.ts @@ -17,9 +17,10 @@ export abstract class ProgressBarUIBase { protected constructor( public parentId: string, public rootId: string, - public show: boolean, + public showSection: boolean, ) { this.createRoot(); + this.showFullSection(this.showSection); } private createRoot = (): void => { @@ -39,12 +40,12 @@ export abstract class ProgressBarUIBase { ctoolsRoot.append(this.htmlContainer); }; - // remember it can't have more parameters because it is used on settings automatically - public render = (value: boolean): void => { - this.show = value; - this.htmlContainer.style.display = this.show ? 'block' : 'none'; - }; + public showFullSection(value: boolean): void { + this.showSection = value; + this.htmlContainer.style.display = value ? 'flex' : 'none'; + } abstract createDOM(): void; - abstract updateDisplay(currentStatus: EStatus, timeStart: number, currentProgress: number): void; + + // abstract updateDisplay(currentStatus: EStatus, timeStart: number, currentProgress: number): void; } From 37c3edfb1a945badc06373574e7be22c7a1042b9 Mon Sep 17 00:00:00 2001 From: Crystian Date: Sun, 22 Sep 2024 22:49:48 +0200 Subject: [PATCH 18/31] union --- web/monitor.css | 81 +++++++++++- web/monitor.js | 65 +++++++--- web/monitor.ts | 74 +++++++---- web/monitorHorizontalUI.d.ts | 21 ++++ web/monitorHorizontalUI.js | 157 +++++++++++++++++++++++ web/monitorHorizontalUI.ts | 233 +++++++++++++++++++++++++++++++++++ web/monitorVerticalUI.js | 2 +- web/monitorVerticalUI.ts | 2 +- web/progressBarUI.js | 2 +- web/progressBarUI.ts | 2 +- web/progressBarUIBase.js | 12 +- web/progressBarUIBase.ts | 11 +- 12 files changed, 612 insertions(+), 50 deletions(-) create mode 100644 web/monitorHorizontalUI.d.ts create mode 100644 web/monitorHorizontalUI.js create mode 100644 web/monitorHorizontalUI.ts diff --git a/web/monitor.css b/web/monitor.css index 0bb150c..e9cf9ec 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -1,4 +1,4 @@ -#crystools-root-old { +#crystools-root-vertical { /*background-color: red;*/ display: flex; width: 100%; @@ -76,3 +76,82 @@ } } + +#crystools-root-horizontal { + /*background-color: red;*/ + display: flex; + /*width: 100%;*/ + flex-direction: row; + margin: 0; + padding: 0; + + .crystools-monitor-container { + /*width: 100%;*/ + /*cursor: crosshair;*/ + /*margin: 4px 0;*/ + /*!* display: flex; by progress bar base *!*/ + /*flex-wrap: wrap;*/ + /*flex-direction: column;*/ + + /*.crystools-monitor {*/ + /* margin: 1px 10px;*/ + /* height: 12px;*/ + /* position: relative;*/ + /* display: flex;*/ + /* align-items: center;*/ + /* flex-direction: row;*/ + /*}*/ + + /*.crystools-text {*/ + /* width: 40px;*/ + /* font-size: 10px;*/ + /* text-align: right;*/ + /* margin-right: 3px;*/ + /*}*/ + + /*.crystools-content {*/ + /* height: 100%;*/ + /* flex-grow: 1;*/ + /* position: relative;*/ + /* background-color: var(--bg-color);*/ + /*}*/ + + /*.crystools-slider {*/ + /* position: absolute;*/ + /* height: 100%;*/ + /* width: 0;*/ + /*}*/ + + /*.crystools-label {*/ + /* position: relative;*/ + /* width: 100%;*/ + /* color: var(--drag-text);*/ + /* font-size: 10px;*/ + /*}*/ + + /*.crystools-progress-bar {*/ + /* cursor: pointer;*/ + /* margin: 0 2px;*/ + /* height: 18px;*/ + /* position: relative;*/ + /* background-color: var(--bg-color);*/ + + /* .crystools-slider {*/ + /* position: absolute;*/ + /* height: 100%;*/ + /* width: 0;*/ + /* transition: width 0.2s;*/ + /* background-color: green;*/ + /* }*/ + + /* .crystools-label {*/ + /* position: absolute;*/ + /* margin: auto 0;*/ + /* width: 100%;*/ + /* color: var(--drag-text);*/ + /* font-size: 14px;*/ + /* }*/ + /*}*/ + } + +} diff --git a/web/monitor.js b/web/monitor.js index a2a440f..875be8d 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -4,6 +4,7 @@ import { MonitorVerticalUI } from './monitorVerticalUI.js'; import { Colors } from './styles.js'; import { convertNumberToPascalCase } from './utils.js'; import { NewMenuOptions } from './progressBarUIBase.js'; +import { MonitorHorizontalUI } from './monitorHorizontalUI.js'; class CrystoolsMonitor { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -78,6 +79,12 @@ class CrystoolsMonitor { writable: true, value: void 0 }); + Object.defineProperty(this, "monitorHorizontalUI", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); Object.defineProperty(this, "createSettingsRate", { enumerable: true, configurable: true, @@ -114,28 +121,31 @@ class CrystoolsMonitor { console.error(error); return; } + const data = { + cpu_utilization: 0, + device: 'cpu', + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }; if (valueNumber === 0) { - this.monitorVerticalUI.updateDisplay({ - cpu_utilization: 0, - device: 'cpu', - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); + this.monitorVerticalUI.updateDisplay(data); + this.monitorHorizontalUI.updateDisplay(data); } this.monitorVerticalUI?.updateAllAnimationDuration(valueNumber); + this.monitorHorizontalUI?.updateAllAnimationDuration(valueNumber); }, }; } @@ -183,6 +193,7 @@ class CrystoolsMonitor { cssColor: Colors.RAM, onChange: async (value) => { this.monitorVerticalUI?.updateWidget(this.monitorRAMElement); + this.monitorHorizontalUI?.updateWidget(this.monitorRAMElement); await this.updateServer({ switchRAM: value }); }, }; @@ -214,12 +225,14 @@ class CrystoolsMonitor { cssColor: Colors.GPU, onChange: async (value) => { this.monitorVerticalUI?.updateWidget(monitorGPUNElement); + this.monitorHorizontalUI?.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index, { utilization: value }); }, }; this.monitorGPUSettings[index] = monitorGPUNElement; app.ui.settings.addSetting(this.monitorGPUSettings[index]); this.monitorVerticalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); + this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); } }); Object.defineProperty(this, "createSettingsGPUVRAM", { @@ -248,12 +261,14 @@ class CrystoolsMonitor { cssColor: Colors.VRAM, onChange: async (value) => { this.monitorVerticalUI?.updateWidget(monitorVRAMNElement); + this.monitorHorizontalUI?.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index, { vram: value }); }, }; this.monitorVRAMSettings[index] = monitorVRAMNElement; app.ui.settings.addSetting(this.monitorVRAMSettings[index]); this.monitorVerticalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); + this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); } }); Object.defineProperty(this, "createSettingsGPUTemp", { @@ -283,12 +298,14 @@ class CrystoolsMonitor { cssColorFinal: Colors.TEMP_END, onChange: async (value) => { this.monitorVerticalUI?.updateWidget(monitorTemperatureNElement); + this.monitorHorizontalUI?.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index, { temperature: value }); }, }; this.monitorTemperatureSettings[index] = monitorTemperatureNElement; app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); this.monitorVerticalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); + this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); } }); Object.defineProperty(this, "createSettingsHDD", { @@ -310,6 +327,7 @@ class CrystoolsMonitor { cssColor: Colors.DISK, onChange: async (value) => { this.monitorVerticalUI?.updateWidget(this.monitorHDDElement); + this.monitorHorizontalUI?.updateWidget(this.monitorHDDElement); await this.updateServer({ switchHDD: value }); }, }; @@ -358,6 +376,7 @@ class CrystoolsMonitor { this.createSettingsGPUUsage(name, index, moreThanOneGPU); }); this.monitorVerticalUI.orderMonitors(); + this.monitorHorizontalUI.orderMonitors(); }); } }); @@ -373,6 +392,10 @@ class CrystoolsMonitor { if (this.monitorVerticalUI.showSection) { this.setup(); } + this.monitorHorizontalUI.showFullSection(this.newMenu !== NewMenuOptions.Disabled); + if (this.monitorHorizontalUI.showSection) { + this.setup(); + } } } }); @@ -444,7 +467,7 @@ class CrystoolsMonitor { configurable: true, writable: true, value: () => { - if (this.monitorVerticalUI) { + if (this.monitorVerticalUI || this.monitorHorizontalUI) { return; } this.createSettingsRate(); @@ -455,6 +478,7 @@ class CrystoolsMonitor { const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); this.monitorVerticalUI = new MonitorVerticalUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu === NewMenuOptions.Disabled)); + this.monitorHorizontalUI = new MonitorHorizontalUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu !== NewMenuOptions.Disabled)); this.updateDisplay(); this.registerListeners(); } @@ -469,6 +493,7 @@ class CrystoolsMonitor { return; } this.monitorVerticalUI.updateDisplay(event.detail); + this.monitorHorizontalUI.updateDisplay(event.detail); }, false); } }); diff --git a/web/monitor.ts b/web/monitor.ts index 5c215cf..0b3f5e7 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -4,6 +4,7 @@ import { MonitorVerticalUI } from './monitorVerticalUI.js'; import { Colors } from './styles.js'; import { convertNumberToPascalCase } from './utils.js'; import { NewMenuOptions } from './progressBarUIBase.js'; +import { MonitorHorizontalUI } from './monitorHorizontalUI.js'; class CrystoolsMonitor { idExtensionName = 'Crystools.monitor'; @@ -20,6 +21,7 @@ class CrystoolsMonitor { monitorTemperatureSettings: TMonitorSettings[] = []; monitorVerticalUI: MonitorVerticalUI; + monitorHorizontalUI: MonitorHorizontalUI; constructor() { window.addEventListener('resize', this.updateDisplay); @@ -58,30 +60,33 @@ class CrystoolsMonitor { return; } - if (valueNumber === 0) { - this.monitorVerticalUI.updateDisplay({ - cpu_utilization: 0, - device: 'cpu', + const data = { + cpu_utilization: 0, + device: 'cpu', - gpus: [ - { - gpu_utilization: 0, - gpu_temperature: 0, - vram_total: 0, - vram_used: 0, - vram_used_percent: 0, - }, - ], - hdd_total: 0, - hdd_used: 0, - hdd_used_percent: 0, - ram_total: 0, - ram_used: 0, - ram_used_percent: 0, - }); + gpus: [ + { + gpu_utilization: 0, + gpu_temperature: 0, + vram_total: 0, + vram_used: 0, + vram_used_percent: 0, + }, + ], + hdd_total: 0, + hdd_used: 0, + hdd_used_percent: 0, + ram_total: 0, + ram_used: 0, + ram_used_percent: 0, + }; + if (valueNumber === 0) { + this.monitorVerticalUI.updateDisplay(data); + this.monitorHorizontalUI.updateDisplay(data); } this.monitorVerticalUI?.updateAllAnimationDuration(valueNumber); + this.monitorHorizontalUI?.updateAllAnimationDuration(valueNumber); }, }; }; @@ -103,6 +108,7 @@ class CrystoolsMonitor { // @ts-ignore onChange: async(value: boolean): Promise => { this.monitorVerticalUI?.updateWidget(this.monitorCPUElement); + // this.monitorHorizontalUI?.updateWidget(this.monitorCPUElement); await this.updateServer({switchCPU: value}); }, }; @@ -125,6 +131,7 @@ class CrystoolsMonitor { // @ts-ignore onChange: async(value: boolean): Promise => { this.monitorVerticalUI?.updateWidget(this.monitorRAMElement); + this.monitorHorizontalUI?.updateWidget(this.monitorRAMElement); await this.updateServer({switchRAM: value}); }, }; @@ -155,6 +162,7 @@ class CrystoolsMonitor { // @ts-ignore onChange: async(value: boolean): Promise => { this.monitorVerticalUI?.updateWidget(monitorGPUNElement); + this.monitorHorizontalUI?.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index, {utilization: value}); }, }; @@ -162,6 +170,7 @@ class CrystoolsMonitor { this.monitorGPUSettings[index] = monitorGPUNElement; app.ui.settings.addSetting(this.monitorGPUSettings[index]); this.monitorVerticalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); + this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); }; createSettingsGPUVRAM = (name: string, index: number, moreThanOneGPU: boolean): void => { @@ -190,6 +199,7 @@ class CrystoolsMonitor { // @ts-ignore onChange: async(value: boolean): Promise => { this.monitorVerticalUI?.updateWidget(monitorVRAMNElement); + this.monitorHorizontalUI?.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index, {vram: value}); }, }; @@ -197,6 +207,7 @@ class CrystoolsMonitor { this.monitorVRAMSettings[index] = monitorVRAMNElement; app.ui.settings.addSetting(this.monitorVRAMSettings[index]); this.monitorVerticalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); + this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); }; createSettingsGPUTemp = (name: string, index: number, moreThanOneGPU: boolean): void => { @@ -226,6 +237,7 @@ class CrystoolsMonitor { // @ts-ignore onChange: async(value: boolean): Promise => { this.monitorVerticalUI?.updateWidget(monitorTemperatureNElement); + this.monitorHorizontalUI?.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index, {temperature: value}); }, }; @@ -233,6 +245,7 @@ class CrystoolsMonitor { this.monitorTemperatureSettings[index] = monitorTemperatureNElement; app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); this.monitorVerticalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); + this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); }; createSettingsHDD = (): void => { @@ -253,6 +266,7 @@ class CrystoolsMonitor { // @ts-ignore onChange: async(value: boolean): Promise => { this.monitorVerticalUI?.updateWidget(this.monitorHDDElement); + this.monitorHorizontalUI?.updateWidget(this.monitorHDDElement); await this.updateServer({switchHDD: value}); }, }; @@ -304,6 +318,7 @@ class CrystoolsMonitor { }); this.monitorVerticalUI.orderMonitors(); + this.monitorHorizontalUI.orderMonitors(); }); }; @@ -317,6 +332,11 @@ class CrystoolsMonitor { if (this.monitorVerticalUI.showSection) { this.setup(); } + + this.monitorHorizontalUI.showFullSection(this.newMenu !== NewMenuOptions.Disabled); + if (this.monitorHorizontalUI.showSection) { + this.setup(); + } } }; @@ -365,7 +385,7 @@ class CrystoolsMonitor { }; setup = (): void => { - if (this.monitorVerticalUI) { + if (this.monitorVerticalUI || this.monitorHorizontalUI) { // this.monitorUIOld.render(0); return; } @@ -391,6 +411,17 @@ class CrystoolsMonitor { (this.newMenu === NewMenuOptions.Disabled), ); + this.monitorHorizontalUI = new MonitorHorizontalUI( + this.monitorCPUElement, + this.monitorRAMElement, + this.monitorHDDElement, + this.monitorGPUSettings, + this.monitorVRAMSettings, + this.monitorTemperatureSettings, + currentRate, + (this.newMenu !== NewMenuOptions.Disabled), + ); + this.updateDisplay(); this.registerListeners(); }; @@ -401,6 +432,7 @@ class CrystoolsMonitor { return; } this.monitorVerticalUI.updateDisplay(event.detail); + this.monitorHorizontalUI.updateDisplay(event.detail); }, false); }; } diff --git a/web/monitorHorizontalUI.d.ts b/web/monitorHorizontalUI.d.ts new file mode 100644 index 0000000..73e97e5 --- /dev/null +++ b/web/monitorHorizontalUI.d.ts @@ -0,0 +1,21 @@ +import { ProgressBarUIBase } from './progressBarUIBase.js'; +export declare class MonitorHorizontalUI extends ProgressBarUIBase { + private monitorCPUElement; + private monitorRAMElement; + private monitorHDDElement; + private monitorGPUSettings; + private monitorVRAMSettings; + private monitorTemperatureSettings; + private currentRate; + constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number, showSection: boolean); + createDOM: () => void; + createDOMGPUMonitor: (monitorSettings?: TMonitorSettings) => void; + orderMonitors: () => void; + updateAllWidget: () => void; + updateWidget: (monitorSettings: TMonitorSettings) => void; + updateDisplay: (data: TStatsData) => void; + updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; + updateAllAnimationDuration: (value: number) => void; + updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; + createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; +} diff --git a/web/monitorHorizontalUI.js b/web/monitorHorizontalUI.js new file mode 100644 index 0000000..ef68f35 --- /dev/null +++ b/web/monitorHorizontalUI.js @@ -0,0 +1,157 @@ +import { ProgressBarUIBase } from './progressBarUIBase.js'; +export class MonitorHorizontalUI extends ProgressBarUIBase { + constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate, showSection) { + super('comfyui-menu-push', 'crystools-root-horizontal', showSection); + Object.defineProperty(this, "monitorCPUElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorCPUElement + }); + Object.defineProperty(this, "monitorRAMElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorRAMElement + }); + Object.defineProperty(this, "monitorHDDElement", { + enumerable: true, + configurable: true, + writable: true, + value: monitorHDDElement + }); + Object.defineProperty(this, "monitorGPUSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorGPUSettings + }); + Object.defineProperty(this, "monitorVRAMSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorVRAMSettings + }); + Object.defineProperty(this, "monitorTemperatureSettings", { + enumerable: true, + configurable: true, + writable: true, + value: monitorTemperatureSettings + }); + Object.defineProperty(this, "currentRate", { + enumerable: true, + configurable: true, + writable: true, + value: currentRate + }); + Object.defineProperty(this, "createDOM", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.htmlContainer.style.order = '2'; + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + } + }); + Object.defineProperty(this, "createDOMGPUMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + } + }); + Object.defineProperty(this, "orderMonitors", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + } + }); + Object.defineProperty(this, "updateAllWidget", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.updateWidget(this.monitorCPUElement); + } + }); + Object.defineProperty(this, "updateWidget", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + } + }); + Object.defineProperty(this, "updateDisplay", { + enumerable: true, + configurable: true, + writable: true, + value: (data) => { + } + }); + Object.defineProperty(this, "updateMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, percent) => { + } + }); + Object.defineProperty(this, "updateAllAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + } + }); + Object.defineProperty(this, "updatedAnimationDuration", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, value) => { + } + }); + Object.defineProperty(this, "createMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + console.log('createMonitor', monitorSettings); + if (!monitorSettings) { + return document.createElement('div'); + } + const htmlMain = document.createElement('div'); + htmlMain.classList.add(monitorSettings.id); + htmlMain.classList.add('crystools-monitor'); + monitorSettings.htmlMonitorRef = htmlMain; + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.classList.add('crystools-text'); + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.classList.add('crystools-content'); + htmlMain.append(htmlMonitorContent); + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.classList.add('crystools-slider'); + if (monitorSettings.cssColorFinal) { + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } + else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.classList.add('crystools-label'); + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + htmlMonitorLabel.innerHTML = '0%'; + return monitorSettings.htmlMonitorRef; + } + }); + this.createDOM(); + } +} diff --git a/web/monitorHorizontalUI.ts b/web/monitorHorizontalUI.ts new file mode 100644 index 0000000..ca324b9 --- /dev/null +++ b/web/monitorHorizontalUI.ts @@ -0,0 +1,233 @@ +import { app } from './comfy/index.js'; +import { ProgressBarUIBase } from './progressBarUIBase.js'; + +export class MonitorHorizontalUI extends ProgressBarUIBase { + // lastMonitor = 1; // just for order on monitors section + + constructor( + private monitorCPUElement: TMonitorSettings, + private monitorRAMElement: TMonitorSettings, + private monitorHDDElement: TMonitorSettings, + private monitorGPUSettings: TMonitorSettings[], + private monitorVRAMSettings: TMonitorSettings[], + private monitorTemperatureSettings: TMonitorSettings[], + private currentRate: number, + showSection: boolean, + ) { + super('comfyui-menu-push', 'crystools-root-horizontal', showSection); + this.createDOM(); + } + + createDOM = (): void => { + this.htmlContainer.style.order = '2'; + this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); + // this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); + // this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); + // this.updateAllAnimationDuration(this.currentRate); + // this.updateAllWidget(); + }; + + createDOMGPUMonitor = (monitorSettings?: TMonitorSettings): void => { + // if (!monitorSettings) { + // return; + // } + // + // this.htmlContainer.append(this.createMonitor(monitorSettings)); + // this.updateAllAnimationDuration(this.currentRate); + // this.updateAllWidget(); + }; + + orderMonitors = (): void => { + // try { + // // @ts-ignore + // this.monitorCPUElement.htmlMonitorRef.style.order = '' + this.lastMonitor++; + // // @ts-ignore + // this.monitorRAMElement.htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // // @ts-ignore + // this.monitorGPUSettings.forEach((_monitorSettings, index) => { + // // @ts-ignore + // this.monitorGPUSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // // @ts-ignore + // this.monitorVRAMSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // // @ts-ignore + // this.monitorTemperatureSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // }); + // // @ts-ignore + // this.monitorHDDElement.htmlMonitorRef.style.order = ''+ this.lastMonitor++; + // } catch (error) { + // console.error('orderMonitors', error); + // } + }; + + updateAllWidget = (): void => { + this.updateWidget(this.monitorCPUElement); + // this.updateWidget(this.monitorRAMElement); + // this.updateWidget(this.monitorHDDElement); + // + // this.monitorGPUSettings.forEach((monitorSettings) => { + // monitorSettings && this.updateWidget(monitorSettings); + // }); + // this.monitorVRAMSettings.forEach((monitorSettings) => { + // monitorSettings && this.updateWidget(monitorSettings); + // }); + // this.monitorTemperatureSettings.forEach((monitorSettings) => { + // monitorSettings && this.updateWidget(monitorSettings); + // }); + }; + + /** + * for the settings menu + * @param monitorSettings + */ + updateWidget = (monitorSettings: TMonitorSettings): void => { + // const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + // if (monitorSettings.htmlMonitorRef) { + // monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + // } + }; + + updateDisplay = (data: TStatsData): void => { + // this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); + // this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); + // this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + // + // if (data.gpus === undefined || data.gpus.length === 0) { + // console.warn('UpdateAllMonitors: no GPU data'); + // return; + // } + // + // this.monitorGPUSettings.forEach((monitorSettings, index) => { + // if (data.gpus[index]) { + // const gpu = data.gpus[index]; + // if (gpu === undefined) { + // // console.error('UpdateAllMonitors: no GPU data for index', index); + // return; + // } + // + // this.updateMonitor(monitorSettings, gpu.gpu_utilization); + // } else { + // // console.error('UpdateAllMonitors: no GPU data for index', index); + // } + // }); + // + // this.monitorVRAMSettings.forEach((monitorSettings, index) => { + // if (data.gpus[index]) { + // const gpu = data.gpus[index]; + // if (gpu === undefined) { + // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + // return; + // } + // + // this.updateMonitor(monitorSettings, gpu.vram_used_percent); + // } else { + // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + // } + // }); + // + // this.monitorTemperatureSettings.forEach((monitorSettings, index) => { + // if (data.gpus[index]) { + // const gpu = data.gpus[index]; + // if (gpu === undefined) { + // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + // return; + // } + // + // this.updateMonitor(monitorSettings, gpu.gpu_temperature); + // if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { + // monitorSettings.htmlMonitorSliderRef.style.backgroundColor = + // `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; + // } + // } else { + // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); + // } + // }); + }; + + updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { + // if (!this.showSection) { + // return; + // } + // + // if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { + // return; + // } + // + // if (percent < 0) { + // return; + // } + // + // // console.log('updateMonitor', monitorSettings.id, percent); + // + // monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; + // monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; + }; + + updateAllAnimationDuration = (value: number): void => { + // this.updatedAnimationDuration(this.monitorCPUElement, value); + // this.updatedAnimationDuration(this.monitorRAMElement, value); + // this.updatedAnimationDuration(this.monitorHDDElement, value); + // this.monitorGPUSettings.forEach((monitorSettings) => { + // monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + // }); + // this.monitorVRAMSettings.forEach((monitorSettings) => { + // monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + // }); + // this.monitorTemperatureSettings.forEach((monitorSettings) => { + // monitorSettings && this.updatedAnimationDuration(monitorSettings, value); + // }); + }; + + updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { + // const slider = monitorSettings.htmlMonitorSliderRef; + // if (!slider) { + // return; + // } + // + // slider.style.transition = `width ${value.toFixed(1)}s`; + }; + + createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { + console.log('createMonitor', monitorSettings); + if (!monitorSettings) { + // just for typescript + return document.createElement('div'); + } + + const htmlMain = document.createElement('div'); + htmlMain.classList.add(monitorSettings.id); + htmlMain.classList.add('crystools-monitor'); + + monitorSettings.htmlMonitorRef = htmlMain; + + if (monitorSettings.title) { + htmlMain.title = monitorSettings.title; + } + + const htmlMonitorText = document.createElement('div'); + htmlMonitorText.classList.add('crystools-text'); + htmlMonitorText.innerHTML = monitorSettings.label; + htmlMain.append(htmlMonitorText); + + const htmlMonitorContent = document.createElement('div'); + htmlMonitorContent.classList.add('crystools-content'); + htmlMain.append(htmlMonitorContent); + + const htmlMonitorSlider = document.createElement('div'); + htmlMonitorSlider.classList.add('crystools-slider'); + if (monitorSettings.cssColorFinal) { + htmlMonitorSlider.style.backgroundColor = + `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; + } else { + htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; + } + monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; + htmlMonitorContent.append(htmlMonitorSlider); + + const htmlMonitorLabel = document.createElement('div'); + htmlMonitorLabel.classList.add('crystools-label'); + monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; + htmlMonitorContent.append(htmlMonitorLabel); + htmlMonitorLabel.innerHTML = '0%'; + return monitorSettings.htmlMonitorRef; + }; +} diff --git a/web/monitorVerticalUI.js b/web/monitorVerticalUI.js index 48b903c..ddcb5a4 100644 --- a/web/monitorVerticalUI.js +++ b/web/monitorVerticalUI.js @@ -2,7 +2,7 @@ import { app } from './comfy/index.js'; import { ProgressBarUIBase } from './progressBarUIBase.js'; export class MonitorVerticalUI extends ProgressBarUIBase { constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate, showSection) { - super('queue-button', 'crystools-root-old', showSection); + super('queue-button', 'crystools-root-vertical', showSection); Object.defineProperty(this, "monitorCPUElement", { enumerable: true, configurable: true, diff --git a/web/monitorVerticalUI.ts b/web/monitorVerticalUI.ts index be587fd..1693997 100644 --- a/web/monitorVerticalUI.ts +++ b/web/monitorVerticalUI.ts @@ -14,7 +14,7 @@ export class MonitorVerticalUI extends ProgressBarUIBase { private currentRate: number, showSection: boolean, ) { - super('queue-button', 'crystools-root-old', showSection); + super('queue-button', 'crystools-root-vertical', showSection); this.createDOM(); } diff --git a/web/progressBarUI.js b/web/progressBarUI.js index 7772dfb..9d4e729 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,7 +1,7 @@ import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export class ProgressBarUI extends ProgressBarUIBase { constructor(showSection, centerNode) { - super('queue-button', 'crystools-root-old', showSection); + super('queue-button', 'crystools-root-vertical', showSection); Object.defineProperty(this, "centerNode", { enumerable: true, configurable: true, diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index 07be192..da2df67 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -12,7 +12,7 @@ export class ProgressBarUI extends ProgressBarUIBase { showSection: boolean, private centerNode: () => void, ) { - super('queue-button', 'crystools-root-old', showSection); + super('queue-button', 'crystools-root-vertical', showSection); this.createDOM(); } diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js index 6b0e4cf..27e96ac 100644 --- a/web/progressBarUIBase.js +++ b/web/progressBarUIBase.js @@ -51,8 +51,16 @@ export class ProgressBarUIBase { if (!ctoolsRoot) { ctoolsRoot = document.createElement('div'); ctoolsRoot.setAttribute('id', this.rootId); - const parentElement = document.getElementById(this.parentId); - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); + let parentElement = document.getElementById(this.parentId); + if (!parentElement) { + parentElement = document.getElementsByClassName(this.parentId)[0]; + } + if (parentElement) { + parentElement.insertAdjacentElement('afterend', ctoolsRoot); + } + else { + console.error('Crystools: parentElement not found', this.parentId); + } } this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); diff --git a/web/progressBarUIBase.ts b/web/progressBarUIBase.ts index db2cf30..dbb578a 100644 --- a/web/progressBarUIBase.ts +++ b/web/progressBarUIBase.ts @@ -31,8 +31,15 @@ export abstract class ProgressBarUIBase { ctoolsRoot.setAttribute('id', this.rootId); // the best parentElement: - const parentElement = document.getElementById(this.parentId); - parentElement?.insertAdjacentElement('afterend', ctoolsRoot); + let parentElement: Element | null | undefined = document.getElementById(this.parentId); + if (!parentElement) { + parentElement = document.getElementsByClassName(this.parentId)[0]; + } + if (parentElement) { + parentElement.insertAdjacentElement('afterend', ctoolsRoot); + } else { + console.error('Crystools: parentElement not found', this.parentId); + } } this.htmlContainer = document.createElement('div'); From 5d37a594871ae6a09367d39d525eb41e7a0c4f78 Mon Sep 17 00:00:00 2001 From: Crystian Date: Mon, 23 Sep 2024 00:51:35 +0200 Subject: [PATCH 19/31] new style for vertical --- web/monitor.css | 132 +++------- web/monitor.js | 128 ++++++---- web/monitor.ts | 125 ++++++---- web/monitorHorizontalUI.d.ts | 21 -- web/monitorHorizontalUI.js | 157 ------------ web/monitorHorizontalUI.ts | 233 ------------------ ...{monitorVerticalUI.d.ts => monitorUI.d.ts} | 4 +- web/{monitorVerticalUI.js => monitorUI.js} | 37 +-- web/{monitorVerticalUI.ts => monitorUI.ts} | 34 +-- web/progressBarUI.js | 2 +- web/progressBarUI.ts | 2 +- web/progressBarUIBase.d.ts | 3 +- web/progressBarUIBase.js | 23 +- web/progressBarUIBase.ts | 20 +- 14 files changed, 228 insertions(+), 693 deletions(-) delete mode 100644 web/monitorHorizontalUI.d.ts delete mode 100644 web/monitorHorizontalUI.js delete mode 100644 web/monitorHorizontalUI.ts rename web/{monitorVerticalUI.d.ts => monitorUI.d.ts} (86%) rename web/{monitorVerticalUI.js => monitorUI.js} (86%) rename web/{monitorVerticalUI.ts => monitorUI.ts} (86%) diff --git a/web/monitor.css b/web/monitor.css index e9cf9ec..f6a0174 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -1,15 +1,20 @@ -#crystools-root-vertical { +.comfy-menu #crystools-root { /*background-color: red;*/ + box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.3); + background-color: var(--comfy-menu-bg); + border-radius: 8px; + border: 1px solid var(--border-color); display: flex; width: 100%; flex-direction: column; - margin: 0; - padding: 0; + margin: 7px; + padding: 5px 0; + gap: 5px; .crystools-monitor-container { width: 100%; cursor: crosshair; - margin: 4px 0; + /*margin: 4px 0;*/ /* display: flex; by progress bar base */ flex-wrap: wrap; flex-direction: column; @@ -21,137 +26,72 @@ display: flex; align-items: center; flex-direction: row; - } - .crystools-text { - width: 40px; - font-size: 10px; - text-align: right; - margin-right: 3px; + .crystools-text { + width: 40px; + font-size: 10px; + text-align: right; + margin-right: 3px; + &:hover{ + font-weight: 600; + color: var(--input-text); + } + } + + .crystools-label { + &:hover{ + font-weight: 800; + color: var(--input-text); + } + } } .crystools-content { height: 100%; flex-grow: 1; position: relative; - background-color: var(--bg-color); + background-color: var(--content-hover-bg) } .crystools-slider { position: absolute; height: 100%; - width: 0; + width: 0; ; + box-shadow: inset 2px 2px 10px rgba(0, 0, 0, 0.2); } .crystools-label { position: relative; width: 100%; - color: var(--drag-text); + color: var(--input-text); font-size: 10px; } .crystools-progress-bar { cursor: pointer; - margin: 0 2px; + margin: 0 9px 0; height: 18px; position: relative; - background-color: var(--bg-color); + border-radius: 3px; + background-color: var(--comfy-input-bg); .crystools-slider { position: absolute; height: 100%; - width: 0; + width: 50%; transition: width 0.2s; background-color: green; + box-shadow: inset 2px 2px 10px rgba(0, 0, 0, 0.3); } .crystools-label { position: absolute; margin: auto 0; width: 100%; - color: var(--drag-text); + color: var(--input-text); font-size: 14px; } } } } - -#crystools-root-horizontal { - /*background-color: red;*/ - display: flex; - /*width: 100%;*/ - flex-direction: row; - margin: 0; - padding: 0; - - .crystools-monitor-container { - /*width: 100%;*/ - /*cursor: crosshair;*/ - /*margin: 4px 0;*/ - /*!* display: flex; by progress bar base *!*/ - /*flex-wrap: wrap;*/ - /*flex-direction: column;*/ - - /*.crystools-monitor {*/ - /* margin: 1px 10px;*/ - /* height: 12px;*/ - /* position: relative;*/ - /* display: flex;*/ - /* align-items: center;*/ - /* flex-direction: row;*/ - /*}*/ - - /*.crystools-text {*/ - /* width: 40px;*/ - /* font-size: 10px;*/ - /* text-align: right;*/ - /* margin-right: 3px;*/ - /*}*/ - - /*.crystools-content {*/ - /* height: 100%;*/ - /* flex-grow: 1;*/ - /* position: relative;*/ - /* background-color: var(--bg-color);*/ - /*}*/ - - /*.crystools-slider {*/ - /* position: absolute;*/ - /* height: 100%;*/ - /* width: 0;*/ - /*}*/ - - /*.crystools-label {*/ - /* position: relative;*/ - /* width: 100%;*/ - /* color: var(--drag-text);*/ - /* font-size: 10px;*/ - /*}*/ - - /*.crystools-progress-bar {*/ - /* cursor: pointer;*/ - /* margin: 0 2px;*/ - /* height: 18px;*/ - /* position: relative;*/ - /* background-color: var(--bg-color);*/ - - /* .crystools-slider {*/ - /* position: absolute;*/ - /* height: 100%;*/ - /* width: 0;*/ - /* transition: width 0.2s;*/ - /* background-color: green;*/ - /* }*/ - - /* .crystools-label {*/ - /* position: absolute;*/ - /* margin: auto 0;*/ - /* width: 100%;*/ - /* color: var(--drag-text);*/ - /* font-size: 14px;*/ - /* }*/ - /*}*/ - } - -} diff --git a/web/monitor.js b/web/monitor.js index 875be8d..acf3ead 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -1,10 +1,9 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; -import { MonitorVerticalUI } from './monitorVerticalUI.js'; +import { MonitorUI } from './monitorUI.js'; import { Colors } from './styles.js'; import { convertNumberToPascalCase } from './utils.js'; import { NewMenuOptions } from './progressBarUIBase.js'; -import { MonitorHorizontalUI } from './monitorHorizontalUI.js'; class CrystoolsMonitor { constructor() { Object.defineProperty(this, "idExtensionName", { @@ -73,13 +72,7 @@ class CrystoolsMonitor { writable: true, value: [] }); - Object.defineProperty(this, "monitorVerticalUI", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "monitorHorizontalUI", { + Object.defineProperty(this, "monitorUI", { enumerable: true, configurable: true, writable: true, @@ -141,11 +134,9 @@ class CrystoolsMonitor { ram_used_percent: 0, }; if (valueNumber === 0) { - this.monitorVerticalUI.updateDisplay(data); - this.monitorHorizontalUI.updateDisplay(data); + this.monitorUI.updateDisplay(data); } - this.monitorVerticalUI?.updateAllAnimationDuration(valueNumber); - this.monitorHorizontalUI?.updateAllAnimationDuration(valueNumber); + this.monitorUI?.updateAllAnimationDuration(valueNumber); }, }; } @@ -168,7 +159,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: Colors.CPU, onChange: async (value) => { - this.monitorVerticalUI?.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorCPUElement); await this.updateServer({ switchCPU: value }); }, }; @@ -192,8 +183,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: Colors.RAM, onChange: async (value) => { - this.monitorVerticalUI?.updateWidget(this.monitorRAMElement); - this.monitorHorizontalUI?.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorRAMElement); await this.updateServer({ switchRAM: value }); }, }; @@ -224,15 +214,13 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: Colors.GPU, onChange: async (value) => { - this.monitorVerticalUI?.updateWidget(monitorGPUNElement); - this.monitorHorizontalUI?.updateWidget(monitorGPUNElement); + this.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index, { utilization: value }); }, }; this.monitorGPUSettings[index] = monitorGPUNElement; app.ui.settings.addSetting(this.monitorGPUSettings[index]); - this.monitorVerticalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); - this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); + this.monitorUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); } }); Object.defineProperty(this, "createSettingsGPUVRAM", { @@ -260,15 +248,13 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: Colors.VRAM, onChange: async (value) => { - this.monitorVerticalUI?.updateWidget(monitorVRAMNElement); - this.monitorHorizontalUI?.updateWidget(monitorVRAMNElement); + this.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index, { vram: value }); }, }; this.monitorVRAMSettings[index] = monitorVRAMNElement; app.ui.settings.addSetting(this.monitorVRAMSettings[index]); - this.monitorVerticalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); - this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); + this.monitorUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); } }); Object.defineProperty(this, "createSettingsGPUTemp", { @@ -297,15 +283,13 @@ class CrystoolsMonitor { cssColor: Colors.TEMP_START, cssColorFinal: Colors.TEMP_END, onChange: async (value) => { - this.monitorVerticalUI?.updateWidget(monitorTemperatureNElement); - this.monitorHorizontalUI?.updateWidget(monitorTemperatureNElement); + this.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index, { temperature: value }); }, }; this.monitorTemperatureSettings[index] = monitorTemperatureNElement; app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); - this.monitorVerticalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); - this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); + this.monitorUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); } }); Object.defineProperty(this, "createSettingsHDD", { @@ -326,8 +310,7 @@ class CrystoolsMonitor { htmlMonitorLabelRef: undefined, cssColor: Colors.DISK, onChange: async (value) => { - this.monitorVerticalUI?.updateWidget(this.monitorHDDElement); - this.monitorHorizontalUI?.updateWidget(this.monitorHDDElement); + this.updateWidget(this.monitorHDDElement); await this.updateServer({ switchHDD: value }); }, }; @@ -375,11 +358,20 @@ class CrystoolsMonitor { this.createSettingsGPUVRAM(name, index, moreThanOneGPU); this.createSettingsGPUUsage(name, index, moreThanOneGPU); }); - this.monitorVerticalUI.orderMonitors(); - this.monitorHorizontalUI.orderMonitors(); + this.finishedLoad(); }); } }); + Object.defineProperty(this, "finishedLoad", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.monitorUI.orderMonitors(); + this.updateAllWidget(); + this.moveMonitor(this.newMenu); + } + }); Object.defineProperty(this, "updateDisplay", { enumerable: true, configurable: true, @@ -388,14 +380,66 @@ class CrystoolsMonitor { const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; - this.monitorVerticalUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); - if (this.monitorVerticalUI.showSection) { - this.setup(); - } - this.monitorHorizontalUI.showFullSection(this.newMenu !== NewMenuOptions.Disabled); - if (this.monitorHorizontalUI.showSection) { + this.monitorUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); + if (this.monitorUI.showSection) { this.setup(); } + this.moveMonitor(this.newMenu); + } + } + }); + Object.defineProperty(this, "moveMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (position) => { + let parentElement; + switch (position) { + case NewMenuOptions.Disabled: + parentElement = document.getElementById('queue-button'); + break; + case NewMenuOptions.Top: + case NewMenuOptions.Bottom: + parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; + break; + } + if (parentElement && this.monitorUI.htmlRoot) { + console.log('moveMonitor1', parentElement); + console.log('moveMonitor2', this.monitorUI.htmlRoot); + parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); + } + else { + console.error('Crystools: parentElement to move monitors not found!', parentElement); + } + } + }); + Object.defineProperty(this, "updateAllWidget", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + } + }); + Object.defineProperty(this, "updateWidget", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings) => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; } } }); @@ -467,7 +511,7 @@ class CrystoolsMonitor { configurable: true, writable: true, value: () => { - if (this.monitorVerticalUI || this.monitorHorizontalUI) { + if (this.monitorUI) { return; } this.createSettingsRate(); @@ -477,8 +521,7 @@ class CrystoolsMonitor { this.createSettings(); const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - this.monitorVerticalUI = new MonitorVerticalUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu === NewMenuOptions.Disabled)); - this.monitorHorizontalUI = new MonitorHorizontalUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu !== NewMenuOptions.Disabled)); + this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu === NewMenuOptions.Disabled)); this.updateDisplay(); this.registerListeners(); } @@ -492,8 +535,7 @@ class CrystoolsMonitor { if (event?.detail === undefined) { return; } - this.monitorVerticalUI.updateDisplay(event.detail); - this.monitorHorizontalUI.updateDisplay(event.detail); + this.monitorUI.updateDisplay(event.detail); }, false); } }); diff --git a/web/monitor.ts b/web/monitor.ts index 0b3f5e7..defea39 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -1,10 +1,9 @@ import { app, api } from './comfy/index.js'; import { commonPrefix } from './common.js'; -import { MonitorVerticalUI } from './monitorVerticalUI.js'; +import { MonitorUI } from './monitorUI.js'; import { Colors } from './styles.js'; import { convertNumberToPascalCase } from './utils.js'; import { NewMenuOptions } from './progressBarUIBase.js'; -import { MonitorHorizontalUI } from './monitorHorizontalUI.js'; class CrystoolsMonitor { idExtensionName = 'Crystools.monitor'; @@ -20,8 +19,7 @@ class CrystoolsMonitor { monitorVRAMSettings: TMonitorSettings[] = []; monitorTemperatureSettings: TMonitorSettings[] = []; - monitorVerticalUI: MonitorVerticalUI; - monitorHorizontalUI: MonitorHorizontalUI; + monitorUI: MonitorUI; constructor() { window.addEventListener('resize', this.updateDisplay); @@ -81,12 +79,10 @@ class CrystoolsMonitor { ram_used_percent: 0, }; if (valueNumber === 0) { - this.monitorVerticalUI.updateDisplay(data); - this.monitorHorizontalUI.updateDisplay(data); + this.monitorUI.updateDisplay(data); } - this.monitorVerticalUI?.updateAllAnimationDuration(valueNumber); - this.monitorHorizontalUI?.updateAllAnimationDuration(valueNumber); + this.monitorUI?.updateAllAnimationDuration(valueNumber); }, }; }; @@ -107,8 +103,7 @@ class CrystoolsMonitor { cssColor: Colors.CPU, // @ts-ignore onChange: async(value: boolean): Promise => { - this.monitorVerticalUI?.updateWidget(this.monitorCPUElement); - // this.monitorHorizontalUI?.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorCPUElement); await this.updateServer({switchCPU: value}); }, }; @@ -130,8 +125,7 @@ class CrystoolsMonitor { cssColor: Colors.RAM, // @ts-ignore onChange: async(value: boolean): Promise => { - this.monitorVerticalUI?.updateWidget(this.monitorRAMElement); - this.monitorHorizontalUI?.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorRAMElement); await this.updateServer({switchRAM: value}); }, }; @@ -161,16 +155,14 @@ class CrystoolsMonitor { cssColor: Colors.GPU, // @ts-ignore onChange: async(value: boolean): Promise => { - this.monitorVerticalUI?.updateWidget(monitorGPUNElement); - this.monitorHorizontalUI?.updateWidget(monitorGPUNElement); + this.updateWidget(monitorGPUNElement); void await this.updateServerGPU(index, {utilization: value}); }, }; this.monitorGPUSettings[index] = monitorGPUNElement; app.ui.settings.addSetting(this.monitorGPUSettings[index]); - this.monitorVerticalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); - this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); + this.monitorUI.createDOMGPUMonitor(this.monitorGPUSettings[index]); }; createSettingsGPUVRAM = (name: string, index: number, moreThanOneGPU: boolean): void => { @@ -198,16 +190,14 @@ class CrystoolsMonitor { cssColor: Colors.VRAM, // @ts-ignore onChange: async(value: boolean): Promise => { - this.monitorVerticalUI?.updateWidget(monitorVRAMNElement); - this.monitorHorizontalUI?.updateWidget(monitorVRAMNElement); + this.updateWidget(monitorVRAMNElement); void await this.updateServerGPU(index, {vram: value}); }, }; this.monitorVRAMSettings[index] = monitorVRAMNElement; app.ui.settings.addSetting(this.monitorVRAMSettings[index]); - this.monitorVerticalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); - this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); + this.monitorUI.createDOMGPUMonitor(this.monitorVRAMSettings[index]); }; createSettingsGPUTemp = (name: string, index: number, moreThanOneGPU: boolean): void => { @@ -236,16 +226,14 @@ class CrystoolsMonitor { cssColorFinal: Colors.TEMP_END, // @ts-ignore onChange: async(value: boolean): Promise => { - this.monitorVerticalUI?.updateWidget(monitorTemperatureNElement); - this.monitorHorizontalUI?.updateWidget(monitorTemperatureNElement); + this.updateWidget(monitorTemperatureNElement); void await this.updateServerGPU(index, {temperature: value}); }, }; this.monitorTemperatureSettings[index] = monitorTemperatureNElement; app.ui.settings.addSetting(this.monitorTemperatureSettings[index]); - this.monitorVerticalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); - this.monitorHorizontalUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); + this.monitorUI.createDOMGPUMonitor(this.monitorTemperatureSettings[index]); }; createSettingsHDD = (): void => { @@ -265,8 +253,7 @@ class CrystoolsMonitor { cssColor: Colors.DISK, // @ts-ignore onChange: async(value: boolean): Promise => { - this.monitorVerticalUI?.updateWidget(this.monitorHDDElement); - this.monitorHorizontalUI?.updateWidget(this.monitorHDDElement); + this.updateWidget(this.monitorHDDElement); await this.updateServer({switchHDD: value}); }, }; @@ -317,30 +304,82 @@ class CrystoolsMonitor { this.createSettingsGPUUsage(name, index, moreThanOneGPU); }); - this.monitorVerticalUI.orderMonitors(); - this.monitorHorizontalUI.orderMonitors(); + this.finishedLoad(); }); }; + finishedLoad = (): void => { + this.monitorUI.orderMonitors(); + this.updateAllWidget(); + this.moveMonitor(this.newMenu); + }; + updateDisplay = (): void => { const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; - this.monitorVerticalUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); - if (this.monitorVerticalUI.showSection) { + this.monitorUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); + if (this.monitorUI.showSection) { this.setup(); } - this.monitorHorizontalUI.showFullSection(this.newMenu !== NewMenuOptions.Disabled); - if (this.monitorHorizontalUI.showSection) { - this.setup(); - } + this.moveMonitor(this.newMenu); } }; + moveMonitor = (position: NewMenuOptions): void => { + let parentElement: Element | null | undefined; + + switch (position) { + case NewMenuOptions.Disabled: + parentElement = document.getElementById('queue-button'); + break; + case NewMenuOptions.Top: + case NewMenuOptions.Bottom: + parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; + break; + } + + if (parentElement && this.monitorUI.htmlRoot) { + console.log('moveMonitor1', parentElement); + console.log('moveMonitor2', this.monitorUI.htmlRoot); + parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); + } else { + console.error('Crystools: parentElement to move monitors not found!', parentElement); + } + + }; + + updateAllWidget = (): void => { + this.updateWidget(this.monitorCPUElement); + this.updateWidget(this.monitorRAMElement); + this.updateWidget(this.monitorHDDElement); + + this.monitorGPUSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorVRAMSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + this.monitorTemperatureSettings.forEach((monitorSettings) => { + monitorSettings && this.updateWidget(monitorSettings); + }); + }; + + /** + * for the settings menu + * @param monitorSettings + */ + updateWidget = (monitorSettings: TMonitorSettings): void => { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + }; + updateServer = async(data: TStatsSettings): Promise => { const resp = await api.fetchApi('/crystools/monitor', { method: 'PATCH', @@ -385,7 +424,7 @@ class CrystoolsMonitor { }; setup = (): void => { - if (this.monitorVerticalUI || this.monitorHorizontalUI) { + if (this.monitorUI) { // this.monitorUIOld.render(0); return; } @@ -400,7 +439,7 @@ class CrystoolsMonitor { parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - this.monitorVerticalUI = new MonitorVerticalUI( + this.monitorUI = new MonitorUI( this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, @@ -411,17 +450,6 @@ class CrystoolsMonitor { (this.newMenu === NewMenuOptions.Disabled), ); - this.monitorHorizontalUI = new MonitorHorizontalUI( - this.monitorCPUElement, - this.monitorRAMElement, - this.monitorHDDElement, - this.monitorGPUSettings, - this.monitorVRAMSettings, - this.monitorTemperatureSettings, - currentRate, - (this.newMenu !== NewMenuOptions.Disabled), - ); - this.updateDisplay(); this.registerListeners(); }; @@ -431,8 +459,7 @@ class CrystoolsMonitor { if (event?.detail === undefined) { return; } - this.monitorVerticalUI.updateDisplay(event.detail); - this.monitorHorizontalUI.updateDisplay(event.detail); + this.monitorUI.updateDisplay(event.detail); }, false); }; } diff --git a/web/monitorHorizontalUI.d.ts b/web/monitorHorizontalUI.d.ts deleted file mode 100644 index 73e97e5..0000000 --- a/web/monitorHorizontalUI.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ProgressBarUIBase } from './progressBarUIBase.js'; -export declare class MonitorHorizontalUI extends ProgressBarUIBase { - private monitorCPUElement; - private monitorRAMElement; - private monitorHDDElement; - private monitorGPUSettings; - private monitorVRAMSettings; - private monitorTemperatureSettings; - private currentRate; - constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number, showSection: boolean); - createDOM: () => void; - createDOMGPUMonitor: (monitorSettings?: TMonitorSettings) => void; - orderMonitors: () => void; - updateAllWidget: () => void; - updateWidget: (monitorSettings: TMonitorSettings) => void; - updateDisplay: (data: TStatsData) => void; - updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; - updateAllAnimationDuration: (value: number) => void; - updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; - createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; -} diff --git a/web/monitorHorizontalUI.js b/web/monitorHorizontalUI.js deleted file mode 100644 index ef68f35..0000000 --- a/web/monitorHorizontalUI.js +++ /dev/null @@ -1,157 +0,0 @@ -import { ProgressBarUIBase } from './progressBarUIBase.js'; -export class MonitorHorizontalUI extends ProgressBarUIBase { - constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate, showSection) { - super('comfyui-menu-push', 'crystools-root-horizontal', showSection); - Object.defineProperty(this, "monitorCPUElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorCPUElement - }); - Object.defineProperty(this, "monitorRAMElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorRAMElement - }); - Object.defineProperty(this, "monitorHDDElement", { - enumerable: true, - configurable: true, - writable: true, - value: monitorHDDElement - }); - Object.defineProperty(this, "monitorGPUSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorGPUSettings - }); - Object.defineProperty(this, "monitorVRAMSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorVRAMSettings - }); - Object.defineProperty(this, "monitorTemperatureSettings", { - enumerable: true, - configurable: true, - writable: true, - value: monitorTemperatureSettings - }); - Object.defineProperty(this, "currentRate", { - enumerable: true, - configurable: true, - writable: true, - value: currentRate - }); - Object.defineProperty(this, "createDOM", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.htmlContainer.style.order = '2'; - this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - } - }); - Object.defineProperty(this, "createDOMGPUMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - } - }); - Object.defineProperty(this, "orderMonitors", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - } - }); - Object.defineProperty(this, "updateAllWidget", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.updateWidget(this.monitorCPUElement); - } - }); - Object.defineProperty(this, "updateWidget", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - } - }); - Object.defineProperty(this, "updateDisplay", { - enumerable: true, - configurable: true, - writable: true, - value: (data) => { - } - }); - Object.defineProperty(this, "updateMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, percent) => { - } - }); - Object.defineProperty(this, "updateAllAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - } - }); - Object.defineProperty(this, "updatedAnimationDuration", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings, value) => { - } - }); - Object.defineProperty(this, "createMonitor", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - console.log('createMonitor', monitorSettings); - if (!monitorSettings) { - return document.createElement('div'); - } - const htmlMain = document.createElement('div'); - htmlMain.classList.add(monitorSettings.id); - htmlMain.classList.add('crystools-monitor'); - monitorSettings.htmlMonitorRef = htmlMain; - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.classList.add('crystools-text'); - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.classList.add('crystools-content'); - htmlMain.append(htmlMonitorContent); - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.classList.add('crystools-slider'); - if (monitorSettings.cssColorFinal) { - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } - else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.classList.add('crystools-label'); - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - htmlMonitorLabel.innerHTML = '0%'; - return monitorSettings.htmlMonitorRef; - } - }); - this.createDOM(); - } -} diff --git a/web/monitorHorizontalUI.ts b/web/monitorHorizontalUI.ts deleted file mode 100644 index ca324b9..0000000 --- a/web/monitorHorizontalUI.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { app } from './comfy/index.js'; -import { ProgressBarUIBase } from './progressBarUIBase.js'; - -export class MonitorHorizontalUI extends ProgressBarUIBase { - // lastMonitor = 1; // just for order on monitors section - - constructor( - private monitorCPUElement: TMonitorSettings, - private monitorRAMElement: TMonitorSettings, - private monitorHDDElement: TMonitorSettings, - private monitorGPUSettings: TMonitorSettings[], - private monitorVRAMSettings: TMonitorSettings[], - private monitorTemperatureSettings: TMonitorSettings[], - private currentRate: number, - showSection: boolean, - ) { - super('comfyui-menu-push', 'crystools-root-horizontal', showSection); - this.createDOM(); - } - - createDOM = (): void => { - this.htmlContainer.style.order = '2'; - this.htmlContainer.append(this.createMonitor(this.monitorCPUElement)); - // this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); - // this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); - // this.updateAllAnimationDuration(this.currentRate); - // this.updateAllWidget(); - }; - - createDOMGPUMonitor = (monitorSettings?: TMonitorSettings): void => { - // if (!monitorSettings) { - // return; - // } - // - // this.htmlContainer.append(this.createMonitor(monitorSettings)); - // this.updateAllAnimationDuration(this.currentRate); - // this.updateAllWidget(); - }; - - orderMonitors = (): void => { - // try { - // // @ts-ignore - // this.monitorCPUElement.htmlMonitorRef.style.order = '' + this.lastMonitor++; - // // @ts-ignore - // this.monitorRAMElement.htmlMonitorRef.style.order = ''+ this.lastMonitor++; - // // @ts-ignore - // this.monitorGPUSettings.forEach((_monitorSettings, index) => { - // // @ts-ignore - // this.monitorGPUSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; - // // @ts-ignore - // this.monitorVRAMSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; - // // @ts-ignore - // this.monitorTemperatureSettings[index].htmlMonitorRef.style.order = ''+ this.lastMonitor++; - // }); - // // @ts-ignore - // this.monitorHDDElement.htmlMonitorRef.style.order = ''+ this.lastMonitor++; - // } catch (error) { - // console.error('orderMonitors', error); - // } - }; - - updateAllWidget = (): void => { - this.updateWidget(this.monitorCPUElement); - // this.updateWidget(this.monitorRAMElement); - // this.updateWidget(this.monitorHDDElement); - // - // this.monitorGPUSettings.forEach((monitorSettings) => { - // monitorSettings && this.updateWidget(monitorSettings); - // }); - // this.monitorVRAMSettings.forEach((monitorSettings) => { - // monitorSettings && this.updateWidget(monitorSettings); - // }); - // this.monitorTemperatureSettings.forEach((monitorSettings) => { - // monitorSettings && this.updateWidget(monitorSettings); - // }); - }; - - /** - * for the settings menu - * @param monitorSettings - */ - updateWidget = (monitorSettings: TMonitorSettings): void => { - // const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - // if (monitorSettings.htmlMonitorRef) { - // monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - // } - }; - - updateDisplay = (data: TStatsData): void => { - // this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - // this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - // this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); - // - // if (data.gpus === undefined || data.gpus.length === 0) { - // console.warn('UpdateAllMonitors: no GPU data'); - // return; - // } - // - // this.monitorGPUSettings.forEach((monitorSettings, index) => { - // if (data.gpus[index]) { - // const gpu = data.gpus[index]; - // if (gpu === undefined) { - // // console.error('UpdateAllMonitors: no GPU data for index', index); - // return; - // } - // - // this.updateMonitor(monitorSettings, gpu.gpu_utilization); - // } else { - // // console.error('UpdateAllMonitors: no GPU data for index', index); - // } - // }); - // - // this.monitorVRAMSettings.forEach((monitorSettings, index) => { - // if (data.gpus[index]) { - // const gpu = data.gpus[index]; - // if (gpu === undefined) { - // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - // return; - // } - // - // this.updateMonitor(monitorSettings, gpu.vram_used_percent); - // } else { - // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - // } - // }); - // - // this.monitorTemperatureSettings.forEach((monitorSettings, index) => { - // if (data.gpus[index]) { - // const gpu = data.gpus[index]; - // if (gpu === undefined) { - // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - // return; - // } - // - // this.updateMonitor(monitorSettings, gpu.gpu_temperature); - // if (monitorSettings.cssColorFinal && monitorSettings.htmlMonitorSliderRef) { - // monitorSettings.htmlMonitorSliderRef.style.backgroundColor = - // `color-mix(in srgb, ${monitorSettings.cssColorFinal} ${gpu.gpu_temperature}%, ${monitorSettings.cssColor})`; - // } - // } else { - // // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); - // } - // }); - }; - - updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { - // if (!this.showSection) { - // return; - // } - // - // if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { - // return; - // } - // - // if (percent < 0) { - // return; - // } - // - // // console.log('updateMonitor', monitorSettings.id, percent); - // - // monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; - // monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; - }; - - updateAllAnimationDuration = (value: number): void => { - // this.updatedAnimationDuration(this.monitorCPUElement, value); - // this.updatedAnimationDuration(this.monitorRAMElement, value); - // this.updatedAnimationDuration(this.monitorHDDElement, value); - // this.monitorGPUSettings.forEach((monitorSettings) => { - // monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - // }); - // this.monitorVRAMSettings.forEach((monitorSettings) => { - // monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - // }); - // this.monitorTemperatureSettings.forEach((monitorSettings) => { - // monitorSettings && this.updatedAnimationDuration(monitorSettings, value); - // }); - }; - - updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => { - // const slider = monitorSettings.htmlMonitorSliderRef; - // if (!slider) { - // return; - // } - // - // slider.style.transition = `width ${value.toFixed(1)}s`; - }; - - createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => { - console.log('createMonitor', monitorSettings); - if (!monitorSettings) { - // just for typescript - return document.createElement('div'); - } - - const htmlMain = document.createElement('div'); - htmlMain.classList.add(monitorSettings.id); - htmlMain.classList.add('crystools-monitor'); - - monitorSettings.htmlMonitorRef = htmlMain; - - if (monitorSettings.title) { - htmlMain.title = monitorSettings.title; - } - - const htmlMonitorText = document.createElement('div'); - htmlMonitorText.classList.add('crystools-text'); - htmlMonitorText.innerHTML = monitorSettings.label; - htmlMain.append(htmlMonitorText); - - const htmlMonitorContent = document.createElement('div'); - htmlMonitorContent.classList.add('crystools-content'); - htmlMain.append(htmlMonitorContent); - - const htmlMonitorSlider = document.createElement('div'); - htmlMonitorSlider.classList.add('crystools-slider'); - if (monitorSettings.cssColorFinal) { - htmlMonitorSlider.style.backgroundColor = - `color-mix(in srgb, ${monitorSettings.cssColorFinal} 0%, ${monitorSettings.cssColor})`; - } else { - htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor; - } - monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider; - htmlMonitorContent.append(htmlMonitorSlider); - - const htmlMonitorLabel = document.createElement('div'); - htmlMonitorLabel.classList.add('crystools-label'); - monitorSettings.htmlMonitorLabelRef = htmlMonitorLabel; - htmlMonitorContent.append(htmlMonitorLabel); - htmlMonitorLabel.innerHTML = '0%'; - return monitorSettings.htmlMonitorRef; - }; -} diff --git a/web/monitorVerticalUI.d.ts b/web/monitorUI.d.ts similarity index 86% rename from web/monitorVerticalUI.d.ts rename to web/monitorUI.d.ts index ec565b7..d52191b 100644 --- a/web/monitorVerticalUI.d.ts +++ b/web/monitorUI.d.ts @@ -1,5 +1,5 @@ import { ProgressBarUIBase } from './progressBarUIBase.js'; -export declare class MonitorVerticalUI extends ProgressBarUIBase { +export declare class MonitorUI extends ProgressBarUIBase { private monitorCPUElement; private monitorRAMElement; private monitorHDDElement; @@ -12,8 +12,6 @@ export declare class MonitorVerticalUI extends ProgressBarUIBase { createDOM: () => void; createDOMGPUMonitor: (monitorSettings?: TMonitorSettings) => void; orderMonitors: () => void; - updateAllWidget: () => void; - updateWidget: (monitorSettings: TMonitorSettings) => void; updateDisplay: (data: TStatsData) => void; updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; updateAllAnimationDuration: (value: number) => void; diff --git a/web/monitorVerticalUI.js b/web/monitorUI.js similarity index 86% rename from web/monitorVerticalUI.js rename to web/monitorUI.js index ddcb5a4..18e46ec 100644 --- a/web/monitorVerticalUI.js +++ b/web/monitorUI.js @@ -1,8 +1,7 @@ -import { app } from './comfy/index.js'; import { ProgressBarUIBase } from './progressBarUIBase.js'; -export class MonitorVerticalUI extends ProgressBarUIBase { +export class MonitorUI extends ProgressBarUIBase { constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate, showSection) { - super('queue-button', 'crystools-root-vertical', showSection); + super('queue-button', 'crystools-root', showSection); Object.defineProperty(this, "monitorCPUElement", { enumerable: true, configurable: true, @@ -61,7 +60,6 @@ export class MonitorVerticalUI extends ProgressBarUIBase { this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); } }); Object.defineProperty(this, "createDOMGPUMonitor", { @@ -74,7 +72,6 @@ export class MonitorVerticalUI extends ProgressBarUIBase { } this.htmlContainer.append(this.createMonitor(monitorSettings)); this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); } }); Object.defineProperty(this, "orderMonitors", { @@ -97,36 +94,6 @@ export class MonitorVerticalUI extends ProgressBarUIBase { } } }); - Object.defineProperty(this, "updateAllWidget", { - enumerable: true, - configurable: true, - writable: true, - value: () => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - } - }); - Object.defineProperty(this, "updateWidget", { - enumerable: true, - configurable: true, - writable: true, - value: (monitorSettings) => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - } - }); Object.defineProperty(this, "updateDisplay", { enumerable: true, configurable: true, diff --git a/web/monitorVerticalUI.ts b/web/monitorUI.ts similarity index 86% rename from web/monitorVerticalUI.ts rename to web/monitorUI.ts index 1693997..2b9679b 100644 --- a/web/monitorVerticalUI.ts +++ b/web/monitorUI.ts @@ -1,7 +1,6 @@ -import { app } from './comfy/index.js'; import { ProgressBarUIBase } from './progressBarUIBase.js'; -export class MonitorVerticalUI extends ProgressBarUIBase { +export class MonitorUI extends ProgressBarUIBase { lastMonitor = 1; // just for order on monitors section constructor( @@ -14,7 +13,7 @@ export class MonitorVerticalUI extends ProgressBarUIBase { private currentRate: number, showSection: boolean, ) { - super('queue-button', 'crystools-root-vertical', showSection); + super('queue-button', 'crystools-root', showSection); this.createDOM(); } @@ -24,7 +23,6 @@ export class MonitorVerticalUI extends ProgressBarUIBase { this.htmlContainer.append(this.createMonitor(this.monitorRAMElement)); this.htmlContainer.append(this.createMonitor(this.monitorHDDElement)); this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); }; createDOMGPUMonitor = (monitorSettings?: TMonitorSettings): void => { @@ -34,7 +32,6 @@ export class MonitorVerticalUI extends ProgressBarUIBase { this.htmlContainer.append(this.createMonitor(monitorSettings)); this.updateAllAnimationDuration(this.currentRate); - this.updateAllWidget(); }; orderMonitors = (): void => { @@ -59,33 +56,6 @@ export class MonitorVerticalUI extends ProgressBarUIBase { } }; - updateAllWidget = (): void => { - this.updateWidget(this.monitorCPUElement); - this.updateWidget(this.monitorRAMElement); - this.updateWidget(this.monitorHDDElement); - - this.monitorGPUSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorVRAMSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - this.monitorTemperatureSettings.forEach((monitorSettings) => { - monitorSettings && this.updateWidget(monitorSettings); - }); - }; - - /** - * for the settings menu - * @param monitorSettings - */ - updateWidget = (monitorSettings: TMonitorSettings): void => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; - } - }; - updateDisplay = (data: TStatsData): void => { this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); diff --git a/web/progressBarUI.js b/web/progressBarUI.js index 9d4e729..d28e485 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,7 +1,7 @@ import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export class ProgressBarUI extends ProgressBarUIBase { constructor(showSection, centerNode) { - super('queue-button', 'crystools-root-vertical', showSection); + super('queue-button', 'crystools-root', showSection); Object.defineProperty(this, "centerNode", { enumerable: true, configurable: true, diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index da2df67..5e6164e 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -12,7 +12,7 @@ export class ProgressBarUI extends ProgressBarUIBase { showSection: boolean, private centerNode: () => void, ) { - super('queue-button', 'crystools-root-vertical', showSection); + super('queue-button', 'crystools-root', showSection); this.createDOM(); } diff --git a/web/progressBarUIBase.d.ts b/web/progressBarUIBase.d.ts index 65a26a6..cad763b 100644 --- a/web/progressBarUIBase.d.ts +++ b/web/progressBarUIBase.d.ts @@ -12,7 +12,8 @@ export declare abstract class ProgressBarUIBase { parentId: string; rootId: string; showSection: boolean; - protected htmlContainer: HTMLDivElement; + htmlRoot: HTMLElement | null; + htmlContainer: HTMLDivElement; protected htmlClassMonitor: string; protected constructor(parentId: string, rootId: string, showSection: boolean); private createRoot; diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js index 27e96ac..674042e 100644 --- a/web/progressBarUIBase.js +++ b/web/progressBarUIBase.js @@ -30,6 +30,12 @@ export class ProgressBarUIBase { writable: true, value: showSection }); + Object.defineProperty(this, "htmlRoot", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); Object.defineProperty(this, "htmlContainer", { enumerable: true, configurable: true, @@ -47,16 +53,13 @@ export class ProgressBarUIBase { configurable: true, writable: true, value: () => { - let ctoolsRoot = document.getElementById(this.rootId); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.rootId); - let parentElement = document.getElementById(this.parentId); - if (!parentElement) { - parentElement = document.getElementsByClassName(this.parentId)[0]; - } + this.htmlRoot = document.getElementById(this.rootId); + if (!this.htmlRoot) { + this.htmlRoot = document.createElement('div'); + this.htmlRoot.setAttribute('id', this.rootId); + const parentElement = document.getElementById(this.parentId); if (parentElement) { - parentElement.insertAdjacentElement('afterend', ctoolsRoot); + parentElement.insertAdjacentElement('afterend', this.htmlRoot); } else { console.error('Crystools: parentElement not found', this.parentId); @@ -64,7 +67,7 @@ export class ProgressBarUIBase { } this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); - ctoolsRoot.append(this.htmlContainer); + this.htmlRoot.append(this.htmlContainer); } }); this.createRoot(); diff --git a/web/progressBarUIBase.ts b/web/progressBarUIBase.ts index dbb578a..4fb5373 100644 --- a/web/progressBarUIBase.ts +++ b/web/progressBarUIBase.ts @@ -11,7 +11,8 @@ export enum NewMenuOptions { } export abstract class ProgressBarUIBase { - protected htmlContainer: HTMLDivElement; + public htmlRoot: HTMLElement | null; + public htmlContainer: HTMLDivElement; protected htmlClassMonitor = 'crystools-monitor-container'; protected constructor( @@ -25,18 +26,15 @@ export abstract class ProgressBarUIBase { private createRoot = (): void => { // IMPORTANT duplicate on crystools-save - let ctoolsRoot = document.getElementById(this.rootId); - if (!ctoolsRoot) { - ctoolsRoot = document.createElement('div'); - ctoolsRoot.setAttribute('id', this.rootId); + this.htmlRoot = document.getElementById(this.rootId); + if (!this.htmlRoot) { + this.htmlRoot = document.createElement('div'); + this.htmlRoot.setAttribute('id', this.rootId); // the best parentElement: - let parentElement: Element | null | undefined = document.getElementById(this.parentId); - if (!parentElement) { - parentElement = document.getElementsByClassName(this.parentId)[0]; - } + const parentElement: Element | null | undefined = document.getElementById(this.parentId); if (parentElement) { - parentElement.insertAdjacentElement('afterend', ctoolsRoot); + parentElement.insertAdjacentElement('afterend', this.htmlRoot); } else { console.error('Crystools: parentElement not found', this.parentId); } @@ -44,7 +42,7 @@ export abstract class ProgressBarUIBase { this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); - ctoolsRoot.append(this.htmlContainer); + this.htmlRoot.append(this.htmlContainer); }; public showFullSection(value: boolean): void { From b9c5d94035e166979d04a48a9f72d502e2981413 Mon Sep 17 00:00:00 2001 From: Crystian Date: Mon, 23 Sep 2024 03:01:52 +0200 Subject: [PATCH 20/31] finallluyyyyyyy! --- web/monitor.css | 89 ++++++++++++++++++++++++++++++++++++-- web/monitor.js | 7 ++- web/monitor.ts | 8 ++-- web/progressBar.js | 1 + web/progressBar.ts | 2 +- web/progressBarUIBase.d.ts | 1 - web/progressBarUIBase.js | 6 +-- web/progressBarUIBase.ts | 12 ++--- 8 files changed, 101 insertions(+), 25 deletions(-) diff --git a/web/monitor.css b/web/monitor.css index f6a0174..cb0373a 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -15,7 +15,7 @@ width: 100%; cursor: crosshair; /*margin: 4px 0;*/ - /* display: flex; by progress bar base */ + display: flex; /* by progress bar base */ flex-wrap: wrap; flex-direction: column; @@ -32,14 +32,15 @@ font-size: 10px; text-align: right; margin-right: 3px; - &:hover{ + + &:hover { font-weight: 600; color: var(--input-text); } } .crystools-label { - &:hover{ + &:hover { font-weight: 800; color: var(--input-text); } @@ -56,7 +57,7 @@ .crystools-slider { position: absolute; height: 100%; - width: 0; ; + width: 0; box-shadow: inset 2px 2px 10px rgba(0, 0, 0, 0.2); } @@ -95,3 +96,83 @@ } } + + + +.comfyui-menu #crystools-root { + /*background-color: red;*/ + display: flex; + flex-direction: row; + flex-shrink: 1; + /*flex-grow: 1;*/ + justify-content: flex-end; + /*width: 100%;*/ + gap: 5px; + height: 100%; + + .crystools-monitor-container { + /*background-color: var(--comfy-menu-bg);*/ + /*width: 100%;*/ + cursor: crosshair; + /*margin: 4px 0;*/ + display: flex; /* by progress bar base */ + flex-wrap: wrap; + flex-direction: row; + justify-content: flex-end; + align-items: center; + height: 100%; + max-width: 600px; + min-width: 300px; + gap: 5px; + + .crystools-monitor { + background-color: var(--comfy-input-bg); + position: relative; + align-items: center; + flex-direction: row; + /*width: 60px;*/ + height: 100%; + + .crystools-text { + font-size: 10px; + text-align: right; + margin-left: 3px; + position: absolute; + bottom: 2px; + z-index: 100; + + /*&:hover {*/ + /* font-weight: 600;*/ + /* color: var(--input-text);*/ + /*}*/ + } + + /*.crystools-label {*/ + /* &:hover {*/ + /* font-weight: 800;*/ + /* color: var(--input-text);*/ + /* }*/ + /*}*/ + } + .crystools-content { + height: 100%; + width: 60px; + position: relative; + } + + .crystools-slider { + position: absolute; + height: 100%; + width: 0; + box-shadow: inset 2px 2px 10px rgba(0, 0, 0, 0.2); + } + + .crystools-label { + position: relative; + width: 100%; + color: var(--input-text); + font-size: 12px; + left: 32px; + } + } +} diff --git a/web/monitor.js b/web/monitor.js index acf3ead..e243e8e 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -380,10 +380,7 @@ class CrystoolsMonitor { const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; - this.monitorUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); - if (this.monitorUI.showSection) { - this.setup(); - } + this.setup(); this.moveMonitor(this.newMenu); } } @@ -511,6 +508,7 @@ class CrystoolsMonitor { configurable: true, writable: true, value: () => { + console.log('setup'); if (this.monitorUI) { return; } @@ -524,6 +522,7 @@ class CrystoolsMonitor { this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu === NewMenuOptions.Disabled)); this.updateDisplay(); this.registerListeners(); + console.log('setup2'); } }); Object.defineProperty(this, "registerListeners", { diff --git a/web/monitor.ts b/web/monitor.ts index defea39..c9ebce8 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -320,10 +320,7 @@ class CrystoolsMonitor { if (newMenu !== this.newMenu) { this.newMenu = newMenu; - this.monitorUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); - if (this.monitorUI.showSection) { - this.setup(); - } + this.setup(); this.moveMonitor(this.newMenu); } @@ -347,6 +344,7 @@ class CrystoolsMonitor { console.log('moveMonitor1', parentElement); console.log('moveMonitor2', this.monitorUI.htmlRoot); parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); + } else { console.error('Crystools: parentElement to move monitors not found!', parentElement); } @@ -424,6 +422,7 @@ class CrystoolsMonitor { }; setup = (): void => { + console.log('setup'); if (this.monitorUI) { // this.monitorUIOld.render(0); return; @@ -452,6 +451,7 @@ class CrystoolsMonitor { this.updateDisplay(); this.registerListeners(); + console.log('setup2'); }; registerListeners = (): void => { diff --git a/web/progressBar.js b/web/progressBar.js index dc14a7f..157361b 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -93,6 +93,7 @@ class CrystoolsProgressBar { this.setup(); } } + this.progressBarUI.htmlContainer.style.display = 'none'; this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } }); diff --git a/web/progressBar.ts b/web/progressBar.ts index ed2d274..bcdd6d2 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -45,7 +45,7 @@ class CrystoolsProgressBar { this.setup(); } } - + this.progressBarUI.htmlContainer.style.display = 'none'; this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); }; diff --git a/web/progressBarUIBase.d.ts b/web/progressBarUIBase.d.ts index cad763b..e71591b 100644 --- a/web/progressBarUIBase.d.ts +++ b/web/progressBarUIBase.d.ts @@ -17,6 +17,5 @@ export declare abstract class ProgressBarUIBase { protected htmlClassMonitor: string; protected constructor(parentId: string, rootId: string, showSection: boolean); private createRoot; - showFullSection(value: boolean): void; abstract createDOM(): void; } diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js index 674042e..612b7ac 100644 --- a/web/progressBarUIBase.js +++ b/web/progressBarUIBase.js @@ -65,16 +65,12 @@ export class ProgressBarUIBase { console.error('Crystools: parentElement not found', this.parentId); } } + this.showSection = true; this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); this.htmlRoot.append(this.htmlContainer); } }); this.createRoot(); - this.showFullSection(this.showSection); - } - showFullSection(value) { - this.showSection = value; - this.htmlContainer.style.display = value ? 'flex' : 'none'; } } diff --git a/web/progressBarUIBase.ts b/web/progressBarUIBase.ts index 4fb5373..55825fa 100644 --- a/web/progressBarUIBase.ts +++ b/web/progressBarUIBase.ts @@ -21,7 +21,7 @@ export abstract class ProgressBarUIBase { public showSection: boolean, ) { this.createRoot(); - this.showFullSection(this.showSection); + // this.showFullSection(this.showSection); } private createRoot = (): void => { @@ -39,16 +39,16 @@ export abstract class ProgressBarUIBase { console.error('Crystools: parentElement not found', this.parentId); } } - + this.showSection = true; this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); this.htmlRoot.append(this.htmlContainer); }; - public showFullSection(value: boolean): void { - this.showSection = value; - this.htmlContainer.style.display = value ? 'flex' : 'none'; - } + // public showFullSection(value: boolean): void { + // this.showSection = value; + // this.htmlContainer.style.display = value ? 'flex' : 'none'; + // } abstract createDOM(): void; From 7d4d7fc81dbd771d26e8cdab51f72d1463910d35 Mon Sep 17 00:00:00 2001 From: Crystian Date: Mon, 23 Sep 2024 03:47:36 +0200 Subject: [PATCH 21/31] new release, with horizontal ui --- README.md | 3 +++ web/monitor.css | 25 +++++++++++++++---------- web/monitor.js | 10 ++++++---- web/monitor.ts | 17 +++++++++++++---- web/progressBar.js | 1 - web/progressBar.ts | 3 ++- web/progressBarUIBase.js | 1 + web/progressBarUIBase.ts | 2 ++ 8 files changed, 42 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 00c59e1..c694aae 100644 --- a/README.md +++ b/README.md @@ -512,6 +512,9 @@ You have predefined switches (string, latent, image, conditioning) but you can u ### Crystools +### 1.18.0 (21/09/2024) +- HORIZONTAL UI! 🎉 + ### 1.17.0 (21/09/2024) - Settings menu reorganized - Preparing for horizontal UI diff --git a/web/monitor.css b/web/monitor.css index cb0373a..b4c0e4c 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -98,20 +98,22 @@ } - .comfyui-menu #crystools-root { /*background-color: red;*/ display: flex; flex-direction: row; flex-shrink: 1; /*flex-grow: 1;*/ - justify-content: flex-end; + justify-content: center; /*width: 100%;*/ - gap: 5px; + gap: 5px; height: 100%; + /*margin: 0 auto;*/ + /*align-items: center;*/ + /*align-self: center;*/ .crystools-monitor-container { - /*background-color: var(--comfy-menu-bg);*/ + /*background-color: var(--comfy-menu-bg);*/ /*width: 100%;*/ cursor: crosshair; /*margin: 4px 0;*/ @@ -126,12 +128,12 @@ gap: 5px; .crystools-monitor { - background-color: var(--comfy-input-bg); + background-color: var(--comfy-input-bg); position: relative; align-items: center; flex-direction: row; /*width: 60px;*/ - height: 100%; + /*height: 100%;*/ .crystools-text { font-size: 10px; @@ -139,7 +141,7 @@ margin-left: 3px; position: absolute; bottom: 2px; - z-index: 100; + z-index: 10; /*&:hover {*/ /* font-weight: 600;*/ @@ -154,9 +156,10 @@ /* }*/ /*}*/ } + .crystools-content { - height: 100%; - width: 60px; + height: 30px; + width: 56px; position: relative; } @@ -172,7 +175,9 @@ width: 100%; color: var(--input-text); font-size: 12px; - left: 32px; + right: 2px; + top: 2px; + text-align: right; } } } diff --git a/web/monitor.js b/web/monitor.js index e243e8e..98889af 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -394,15 +394,19 @@ class CrystoolsMonitor { switch (position) { case NewMenuOptions.Disabled: parentElement = document.getElementById('queue-button'); + if (document.getElementById('ProgressBarUI')) { + document.getElementById('ProgressBarUI').style.display = 'flex'; + } break; case NewMenuOptions.Top: case NewMenuOptions.Bottom: + if (document.getElementById('ProgressBarUI')) { + document.getElementById('ProgressBarUI').style.display = 'none'; + } parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; break; } if (parentElement && this.monitorUI.htmlRoot) { - console.log('moveMonitor1', parentElement); - console.log('moveMonitor2', this.monitorUI.htmlRoot); parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); } else { @@ -508,7 +512,6 @@ class CrystoolsMonitor { configurable: true, writable: true, value: () => { - console.log('setup'); if (this.monitorUI) { return; } @@ -522,7 +525,6 @@ class CrystoolsMonitor { this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu === NewMenuOptions.Disabled)); this.updateDisplay(); this.registerListeners(); - console.log('setup2'); } }); Object.defineProperty(this, "registerListeners", { diff --git a/web/monitor.ts b/web/monitor.ts index c9ebce8..04dd8ec 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -333,16 +333,27 @@ class CrystoolsMonitor { switch (position) { case NewMenuOptions.Disabled: parentElement = document.getElementById('queue-button'); + // TODO remove this + if (document.getElementById('ProgressBarUI')) { + // @ts-ignore + document.getElementById('ProgressBarUI').style.display = 'flex'; + + } break; case NewMenuOptions.Top: case NewMenuOptions.Bottom: + // TODO remove this + if (document.getElementById('ProgressBarUI')) { + // @ts-ignore + document.getElementById('ProgressBarUI').style.display = 'none'; + } parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; break; } if (parentElement && this.monitorUI.htmlRoot) { - console.log('moveMonitor1', parentElement); - console.log('moveMonitor2', this.monitorUI.htmlRoot); + // console.log('moveMonitor1', parentElement); + // console.log('moveMonitor2', this.monitorUI.htmlRoot); parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); } else { @@ -422,7 +433,6 @@ class CrystoolsMonitor { }; setup = (): void => { - console.log('setup'); if (this.monitorUI) { // this.monitorUIOld.render(0); return; @@ -451,7 +461,6 @@ class CrystoolsMonitor { this.updateDisplay(); this.registerListeners(); - console.log('setup2'); }; registerListeners = (): void => { diff --git a/web/progressBar.js b/web/progressBar.js index 157361b..dc14a7f 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -93,7 +93,6 @@ class CrystoolsProgressBar { this.setup(); } } - this.progressBarUI.htmlContainer.style.display = 'none'; this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); } }); diff --git a/web/progressBar.ts b/web/progressBar.ts index bcdd6d2..46e77bb 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -45,7 +45,8 @@ class CrystoolsProgressBar { this.setup(); } } - this.progressBarUI.htmlContainer.style.display = 'none'; + // this.progressBarUI.showSection = (this.newMenu !== NewMenuOptions.Disabled); + // this.progressBarUI.htmlContainer.style.display = 'none'; this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); }; diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js index 612b7ac..871a920 100644 --- a/web/progressBarUIBase.js +++ b/web/progressBarUIBase.js @@ -68,6 +68,7 @@ export class ProgressBarUIBase { this.showSection = true; this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); + this.htmlContainer.setAttribute('id', this.constructor.name); this.htmlRoot.append(this.htmlContainer); } }); diff --git a/web/progressBarUIBase.ts b/web/progressBarUIBase.ts index 55825fa..b1ff7c1 100644 --- a/web/progressBarUIBase.ts +++ b/web/progressBarUIBase.ts @@ -39,9 +39,11 @@ export abstract class ProgressBarUIBase { console.error('Crystools: parentElement not found', this.parentId); } } + // TODO remove this this.showSection = true; this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); + this.htmlContainer.setAttribute('id', this.constructor.name); this.htmlRoot.append(this.htmlContainer); }; From 76b608cc99e27994645a13155c434820d70ef201 Mon Sep 17 00:00:00 2001 From: Crystian Date: Mon, 23 Sep 2024 14:46:56 +0200 Subject: [PATCH 22/31] height and width configurable --- __init__.py | 2 +- core/version.py | 2 +- pyproject.toml | 2 +- version | 2 +- web/monitor.css | 19 ++++--- web/monitor.js | 136 +++++++++++++++++++++++++++++++++++++++++---- web/monitor.ts | 133 +++++++++++++++++++++++++++++++++++--------- web/monitorUI.d.ts | 4 +- web/monitorUI.js | 37 ++++++++++-- web/monitorUI.ts | 31 +++++++++-- web/types.d.ts | 1 + web/utils.d.ts | 2 + web/utils.js | 16 ++++++ web/utils.ts | 19 +++++++ 14 files changed, 346 insertions(+), 60 deletions(-) diff --git a/__init__.py b/__init__.py index 12b2ec0..05db9ae 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ @author: Crystian @title: Crystools @nickname: Crystools -@version: 1.18.0 +@version: 1.18.1 @project: "https://github.com/crystian/ComfyUI-Crystools", @description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia """ diff --git a/core/version.py b/core/version.py index 9bc7482..cefde7d 100644 --- a/core/version.py +++ b/core/version.py @@ -1 +1 @@ -version = "1.18.0" +version = "1.18.1" diff --git a/pyproject.toml b/pyproject.toml index f971752..807a9d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-crystools" description = "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." -version = "1.18.0" +version = "1.18.1" license = { file = "LICENSE" } dependencies = ["deepdiff", "torch", "numpy", "Pillow", "pynvml", "py-cpuinfo"] diff --git a/version b/version index 84cc529..ec6d649 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.18.0 +1.18.1 diff --git a/web/monitor.css b/web/monitor.css index b4c0e4c..14b4f51 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -103,14 +103,15 @@ display: flex; flex-direction: row; flex-shrink: 1; - /*flex-grow: 1;*/ + flex-grow: 100; justify-content: center; + /*gap: 5px;*/ /*width: 100%;*/ - gap: 5px; - height: 100%; + /*height: 100%;*/ /*margin: 0 auto;*/ /*align-items: center;*/ /*align-self: center;*/ + min-width: 200px; .crystools-monitor-container { /*background-color: var(--comfy-menu-bg);*/ @@ -122,10 +123,10 @@ flex-direction: row; justify-content: flex-end; align-items: center; - height: 100%; - max-width: 600px; - min-width: 300px; gap: 5px; + /*height: 100%;*/ + /*max-width: 300px;*/ + /*min-width: 200px;*/ .crystools-monitor { background-color: var(--comfy-input-bg); @@ -140,6 +141,7 @@ text-align: right; margin-left: 3px; position: absolute; + font-weight: 100; bottom: 2px; z-index: 10; @@ -158,8 +160,6 @@ } .crystools-content { - height: 30px; - width: 56px; position: relative; } @@ -174,7 +174,8 @@ position: relative; width: 100%; color: var(--input-text); - font-size: 12px; + font-weight: 500; + font-size: 11px; right: 2px; top: 2px; text-align: right; diff --git a/web/monitor.js b/web/monitor.js index 98889af..adaaeb0 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -30,6 +30,18 @@ class CrystoolsMonitor { writable: true, value: void 0 }); + Object.defineProperty(this, "settingsMonitorHeight", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "settingsMonitorWidth", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); Object.defineProperty(this, "monitorCPUElement", { enumerable: true, configurable: true, @@ -78,6 +90,30 @@ class CrystoolsMonitor { writable: true, value: void 0 }); + Object.defineProperty(this, "monitorWidthId", { + enumerable: true, + configurable: true, + writable: true, + value: 'Crystools.MonitorWidth' + }); + Object.defineProperty(this, "monitorWidth", { + enumerable: true, + configurable: true, + writable: true, + value: 60 + }); + Object.defineProperty(this, "monitorHeightId", { + enumerable: true, + configurable: true, + writable: true, + value: 'Crystools.MonitorHeight' + }); + Object.defineProperty(this, "monitorHeight", { + enumerable: true, + configurable: true, + writable: true, + value: 30 + }); Object.defineProperty(this, "createSettingsRate", { enumerable: true, configurable: true, @@ -86,13 +122,13 @@ class CrystoolsMonitor { this.settingsRate = { id: 'Crystools.RefreshRate', name: 'Refresh per second', - category: ['Crystools', this.menuPrefix + ' Refresh Rate'], + category: ['Crystools', this.menuPrefix + ' Configuration', 'refresh'], tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', type: 'slider', attrs: { min: 0, max: 2, - step: 0.25, + step: .25, }, defaultValue: .5, onChange: async (value) => { @@ -207,7 +243,7 @@ class CrystoolsMonitor { type: 'boolean', label, symbol: '%', - title: `${index}: ${name}`, + monitorTitle: `${index}: ${name}`, defaultValue: true, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, @@ -241,7 +277,7 @@ class CrystoolsMonitor { type: 'boolean', label: label, symbol: '%', - title: `${index}: ${name}`, + monitorTitle: `${index}: ${name}`, defaultValue: true, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, @@ -275,7 +311,7 @@ class CrystoolsMonitor { type: 'boolean', label: label, symbol: '°', - title: `${index}: ${name}`, + monitorTitle: `${index}: ${name}`, defaultValue: true, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, @@ -335,12 +371,84 @@ class CrystoolsMonitor { }; } }); + Object.defineProperty(this, "createSettingsMonitorWidth", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.settingsMonitorWidth = { + id: this.monitorWidthId, + name: 'Pixel Width', + category: ['Crystools', this.menuPrefix + ' Configuration', 'width'], + tooltip: 'The width of the monitor in pixels on the UI (only on horizontal UI)', + type: 'slider', + attrs: { + min: 60, + max: 100, + step: 1, + }, + defaultValue: this.monitorWidth, + onChange: (value) => { + let valueNumber; + try { + valueNumber = parseInt(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } + catch (error) { + console.error(error); + return; + } + const h = app.ui.settings.getSettingValue(this.monitorHeightId, this.monitorHeight); + this.monitorUI?.updateMonitorSize(valueNumber, h); + }, + }; + } + }); + Object.defineProperty(this, "createSettingsMonitorHeight", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.settingsMonitorHeight = { + id: this.monitorHeightId, + name: 'Pixel Height', + category: ['Crystools', this.menuPrefix + ' Configuration', 'height'], + tooltip: 'The height of the monitor in pixels on the UI (only on horizontal UI)', + type: 'slider', + attrs: { + min: 16, + max: 50, + step: 1, + }, + defaultValue: this.monitorHeight, + onChange: (value) => { + let valueNumber; + try { + valueNumber = parseInt(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } + catch (error) { + console.error(error); + return; + } + const w = app.ui.settings.getSettingValue(this.monitorWidthId, this.monitorWidth); + this.monitorUI?.updateMonitorSize(w, valueNumber); + }, + }; + } + }); Object.defineProperty(this, "createSettings", { enumerable: true, configurable: true, writable: true, value: () => { app.ui.settings.addSetting(this.settingsRate); + app.ui.settings.addSetting(this.settingsMonitorHeight); + app.ui.settings.addSetting(this.settingsMonitorWidth); app.ui.settings.addSetting(this.monitorRAMElement); app.ui.settings.addSetting(this.monitorCPUElement); void this.getHDDsFromServer().then((data) => { @@ -370,6 +478,9 @@ class CrystoolsMonitor { this.monitorUI.orderMonitors(); this.updateAllWidget(); this.moveMonitor(this.newMenu); + const w = app.ui.settings.getSettingValue(this.monitorWidthId, this.monitorWidth); + const h = app.ui.settings.getSettingValue(this.monitorHeightId, this.monitorHeight); + this.monitorUI.updateMonitorSize(w, h); } }); Object.defineProperty(this, "updateDisplay", { @@ -377,12 +488,13 @@ class CrystoolsMonitor { configurable: true, writable: true, value: () => { - const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - if (newMenu !== this.newMenu) { - this.newMenu = newMenu; - this.setup(); - this.moveMonitor(this.newMenu); - } + setTimeout(() => { + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + this.moveMonitor(this.newMenu); + } + }); } }); Object.defineProperty(this, "moveMonitor", { @@ -516,6 +628,8 @@ class CrystoolsMonitor { return; } this.createSettingsRate(); + this.createSettingsMonitorHeight(); + this.createSettingsMonitorWidth(); this.createSettingsCPU(); this.createSettingsRAM(); this.createSettingsHDD(); diff --git a/web/monitor.ts b/web/monitor.ts index 04dd8ec..3dde734 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -6,20 +6,27 @@ import { convertNumberToPascalCase } from './utils.js'; import { NewMenuOptions } from './progressBarUIBase.js'; class CrystoolsMonitor { - idExtensionName = 'Crystools.monitor'; - menuPrefix = commonPrefix; - newMenu: NewMenuOptions = NewMenuOptions.Disabled; + readonly idExtensionName = 'Crystools.monitor'; + private readonly menuPrefix = commonPrefix; + private newMenu: NewMenuOptions = NewMenuOptions.Disabled; - settingsRate: TMonitorSettings; - monitorCPUElement: TMonitorSettings; - monitorRAMElement: TMonitorSettings; - monitorHDDElement: TMonitorSettings; - settingsHDD: TMonitorSettings; - monitorGPUSettings: TMonitorSettings[] = []; - monitorVRAMSettings: TMonitorSettings[] = []; - monitorTemperatureSettings: TMonitorSettings[] = []; + private settingsRate: TMonitorSettings; + private settingsMonitorHeight: TMonitorSettings; + private settingsMonitorWidth: TMonitorSettings; + private monitorCPUElement: TMonitorSettings; + private monitorRAMElement: TMonitorSettings; + private monitorHDDElement: TMonitorSettings; + private settingsHDD: TMonitorSettings; + private monitorGPUSettings: TMonitorSettings[] = []; + private monitorVRAMSettings: TMonitorSettings[] = []; + private monitorTemperatureSettings: TMonitorSettings[] = []; - monitorUI: MonitorUI; + private monitorUI: MonitorUI; + + private readonly monitorWidthId = 'Crystools.MonitorWidth'; + private readonly monitorWidth = 60; + private readonly monitorHeightId = 'Crystools.MonitorHeight'; + private readonly monitorHeight = 30; constructor() { window.addEventListener('resize', this.updateDisplay); @@ -29,15 +36,16 @@ class CrystoolsMonitor { this.settingsRate = { id: 'Crystools.RefreshRate', name: 'Refresh per second', - category: ['Crystools', this.menuPrefix + ' Refresh Rate'], + category: ['Crystools', this.menuPrefix + ' Configuration', 'refresh'], tooltip: 'This is the time (in seconds) between each update of the monitors, 0 means no refresh', type: 'slider', attrs: { min: 0, max: 2, - step: 0.25, + step: .25, }, defaultValue: .5, + // @ts-ignore onChange: async(value: string): Promise => { let valueNumber: number; @@ -147,7 +155,7 @@ class CrystoolsMonitor { type: 'boolean', label, symbol: '%', - title: `${index}: ${name}`, + monitorTitle: `${index}: ${name}`, defaultValue: true, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, @@ -182,7 +190,7 @@ class CrystoolsMonitor { type: 'boolean', label: label, symbol: '%', - title: `${index}: ${name}`, + monitorTitle: `${index}: ${name}`, defaultValue: true, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, @@ -217,7 +225,7 @@ class CrystoolsMonitor { type: 'boolean', label: label, symbol: '°', - title: `${index}: ${name}`, + monitorTitle: `${index}: ${name}`, defaultValue: true, htmlMonitorRef: undefined, htmlMonitorSliderRef: undefined, @@ -281,8 +289,76 @@ class CrystoolsMonitor { }; }; + createSettingsMonitorWidth = (): void => { + this.settingsMonitorWidth = { + id: this.monitorWidthId, + name: 'Pixel Width', + category: ['Crystools', this.menuPrefix + ' Configuration', 'width'], + tooltip: 'The width of the monitor in pixels on the UI (only on horizontal UI)', + type: 'slider', + attrs: { + min: 60, + max: 100, + step: 1, + }, + defaultValue: this.monitorWidth, + // @ts-ignore + onChange: (value: string): void => { + let valueNumber: number; + + try { + valueNumber = parseInt(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } catch (error) { + console.error(error); + return; + } + + const h = app.ui.settings.getSettingValue(this.monitorHeightId, this.monitorHeight); + this.monitorUI?.updateMonitorSize(valueNumber, h); + }, + }; + }; + + createSettingsMonitorHeight = (): void => { + this.settingsMonitorHeight = { + id: this.monitorHeightId, + name: 'Pixel Height', + category: ['Crystools', this.menuPrefix + ' Configuration', 'height'], + tooltip: 'The height of the monitor in pixels on the UI (only on horizontal UI)', + type: 'slider', + attrs: { + min: 16, + max: 50, + step: 1, + }, + defaultValue: this.monitorHeight, + // @ts-ignore + onChange: (value: string): void => { + let valueNumber: number; + + try { + valueNumber = parseInt(value); + if (isNaN(valueNumber)) { + throw new Error('invalid value'); + } + } catch (error) { + console.error(error); + return; + } + + const w = app.ui.settings.getSettingValue(this.monitorWidthId, this.monitorWidth); + this.monitorUI?.updateMonitorSize(w, valueNumber); + }, + }; + }; + createSettings = (): void => { app.ui.settings.addSetting(this.settingsRate); + app.ui.settings.addSetting(this.settingsMonitorHeight); + app.ui.settings.addSetting(this.settingsMonitorWidth); app.ui.settings.addSetting(this.monitorRAMElement); app.ui.settings.addSetting(this.monitorCPUElement); @@ -312,19 +388,20 @@ class CrystoolsMonitor { this.monitorUI.orderMonitors(); this.updateAllWidget(); this.moveMonitor(this.newMenu); + + const w = app.ui.settings.getSettingValue(this.monitorWidthId, this.monitorWidth); + const h = app.ui.settings.getSettingValue(this.monitorHeightId, this.monitorHeight); + this.monitorUI.updateMonitorSize(w, h); }; updateDisplay = (): void => { - const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - - if (newMenu !== this.newMenu) { - this.newMenu = newMenu; - - this.setup(); - - this.moveMonitor(this.newMenu); - } - + setTimeout(() => { + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + this.moveMonitor(this.newMenu); + } + }); }; moveMonitor = (position: NewMenuOptions): void => { @@ -439,6 +516,8 @@ class CrystoolsMonitor { } this.createSettingsRate(); + this.createSettingsMonitorHeight(); + this.createSettingsMonitorWidth(); this.createSettingsCPU(); this.createSettingsRAM(); this.createSettingsHDD(); diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts index d52191b..af5056b 100644 --- a/web/monitorUI.d.ts +++ b/web/monitorUI.d.ts @@ -8,13 +8,15 @@ export declare class MonitorUI extends ProgressBarUIBase { private monitorTemperatureSettings; private currentRate; lastMonitor: number; + styleSheet: HTMLStyleElement; constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number, showSection: boolean); createDOM: () => void; createDOMGPUMonitor: (monitorSettings?: TMonitorSettings) => void; orderMonitors: () => void; updateDisplay: (data: TStatsData) => void; - updateMonitor: (monitorSettings: TMonitorSettings, percent: number) => void; + updateMonitor: (monitorSettings: TMonitorSettings, percent: number, used?: number, total?: number) => void; updateAllAnimationDuration: (value: number) => void; updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; + updateMonitorSize: (width: number, height: number) => void; } diff --git a/web/monitorUI.js b/web/monitorUI.js index 18e46ec..1d8be8d 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,4 +1,5 @@ import { ProgressBarUIBase } from './progressBarUIBase.js'; +import { createStyleSheet, formatBytes } from './utils.js'; export class MonitorUI extends ProgressBarUIBase { constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate, showSection) { super('queue-button', 'crystools-root', showSection); @@ -50,6 +51,12 @@ export class MonitorUI extends ProgressBarUIBase { writable: true, value: 1 }); + Object.defineProperty(this, "styleSheet", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); Object.defineProperty(this, "createDOM", { enumerable: true, configurable: true, @@ -100,8 +107,8 @@ export class MonitorUI extends ProgressBarUIBase { writable: true, value: (data) => { this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent, data.ram_used, data.ram_total); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent, data.hdd_used, data.hdd_total); if (data.gpus === undefined || data.gpus.length === 0) { console.warn('UpdateAllMonitors: no GPU data'); return; @@ -123,7 +130,7 @@ export class MonitorUI extends ProgressBarUIBase { if (gpu === undefined) { return; } - this.updateMonitor(monitorSettings, gpu.vram_used_percent); + this.updateMonitor(monitorSettings, gpu.vram_used_percent, gpu.vram_used, gpu.vram_total); } else { } @@ -149,7 +156,7 @@ export class MonitorUI extends ProgressBarUIBase { enumerable: true, configurable: true, writable: true, - value: (monitorSettings, percent) => { + value: (monitorSettings, percent, used, total) => { if (!this.showSection) { return; } @@ -159,6 +166,16 @@ export class MonitorUI extends ProgressBarUIBase { if (percent < 0) { return; } + const prefix = monitorSettings.monitorTitle ? monitorSettings.monitorTitle + ' - ' : ''; + let title = `${Math.floor(percent)}${monitorSettings.symbol}`; + let postfix = ''; + if (used !== undefined && total !== undefined) { + postfix = ` - ${formatBytes(used)} / ${formatBytes(total)} GB`; + } + title = `${prefix}${title}${postfix}`; + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.title = title; + } monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; } @@ -235,6 +252,18 @@ export class MonitorUI extends ProgressBarUIBase { return monitorSettings.htmlMonitorRef; } }); + Object.defineProperty(this, "updateMonitorSize", { + enumerable: true, + configurable: true, + writable: true, + value: (width, height) => { + this.styleSheet.innerText = ` + .comfyui-menu #crystools-root .crystools-monitor .crystools-content { + height: ${height}px; width: ${width}px; + }`; + } + }); this.createDOM(); + this.styleSheet = createStyleSheet('crystools-monitors-size'); } } diff --git a/web/monitorUI.ts b/web/monitorUI.ts index 2b9679b..cbf66cc 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -1,7 +1,9 @@ import { ProgressBarUIBase } from './progressBarUIBase.js'; +import { createStyleSheet, formatBytes } from './utils.js'; export class MonitorUI extends ProgressBarUIBase { lastMonitor = 1; // just for order on monitors section + styleSheet: HTMLStyleElement; constructor( private monitorCPUElement: TMonitorSettings, @@ -15,6 +17,8 @@ export class MonitorUI extends ProgressBarUIBase { ) { super('queue-button', 'crystools-root', showSection); this.createDOM(); + + this.styleSheet = createStyleSheet('crystools-monitors-size'); } createDOM = (): void => { @@ -58,8 +62,8 @@ export class MonitorUI extends ProgressBarUIBase { updateDisplay = (data: TStatsData): void => { this.updateMonitor(this.monitorCPUElement, data.cpu_utilization); - this.updateMonitor(this.monitorRAMElement, data.ram_used_percent); - this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent); + this.updateMonitor(this.monitorRAMElement, data.ram_used_percent, data.ram_used, data.ram_total); + this.updateMonitor(this.monitorHDDElement, data.hdd_used_percent, data.hdd_used, data.hdd_total); if (data.gpus === undefined || data.gpus.length === 0) { console.warn('UpdateAllMonitors: no GPU data'); @@ -88,7 +92,7 @@ export class MonitorUI extends ProgressBarUIBase { return; } - this.updateMonitor(monitorSettings, gpu.vram_used_percent); + this.updateMonitor(monitorSettings, gpu.vram_used_percent, gpu.vram_used, gpu.vram_total); } else { // console.error('UpdateAllMonitors: no GPU VRAM data for index', index); } @@ -113,7 +117,8 @@ export class MonitorUI extends ProgressBarUIBase { }); }; - updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => { + // eslint-disable-next-line complexity + updateMonitor = (monitorSettings: TMonitorSettings, percent: number, used?: number, total?: number): void => { if (!this.showSection) { return; } @@ -127,7 +132,18 @@ export class MonitorUI extends ProgressBarUIBase { } // console.log('updateMonitor', monitorSettings.id, percent); + const prefix = monitorSettings.monitorTitle ? monitorSettings.monitorTitle + ' - ' : ''; + let title = `${Math.floor(percent)}${monitorSettings.symbol}`; + let postfix = ''; + if(used !== undefined && total !== undefined) { + postfix = ` - ${formatBytes(used)} / ${formatBytes(total)} GB`; + } + title = `${prefix}${title}${postfix}`; + + if(monitorSettings.htmlMonitorRef){ + monitorSettings.htmlMonitorRef.title = title; + } monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}${monitorSettings.symbol}`; monitorSettings.htmlMonitorSliderRef.style.width = `${Math.floor(percent)}%`; }; @@ -199,4 +215,11 @@ export class MonitorUI extends ProgressBarUIBase { htmlMonitorLabel.innerHTML = '0%'; return monitorSettings.htmlMonitorRef; }; + + updateMonitorSize = (width: number, height: number): void => { + this.styleSheet.innerText = ` + .comfyui-menu #crystools-root .crystools-monitor .crystools-content { + height: ${height}px; width: ${width}px; + }`; + }; } diff --git a/web/types.d.ts b/web/types.d.ts index 690086d..3480acf 100644 --- a/web/types.d.ts +++ b/web/types.d.ts @@ -46,6 +46,7 @@ type TMonitorSettings = { category: string[], // for settings location label: string, // on monitor symbol: string, // on monitor + monitorTitle?: string, // on monitor title?: string, // on monitor tooltip?: string, // on settings type: 'boolean' | 'number' | 'string' | 'slider' | 'combo', diff --git a/web/utils.d.ts b/web/utils.d.ts index 01e61fc..05c0232 100644 --- a/web/utils.d.ts +++ b/web/utils.d.ts @@ -2,3 +2,5 @@ export declare function numberToWords(num: number): string; export declare function toPascalCase(strings: string[]): string; export declare function convertNumberToPascalCase(num: number): string; export declare function injectCss(href: string): Promise; +export declare function formatBytes(bytes: number): string; +export declare function createStyleSheet(id: string): HTMLStyleElement; diff --git a/web/utils.js b/web/utils.js index e9e0a38..f3c2c4a 100644 --- a/web/utils.js +++ b/web/utils.js @@ -55,3 +55,19 @@ export function injectCss(href) { document.head.appendChild(link); }); } +export function formatBytes(bytes) { + if (bytes === 0) + return '0 Bytes'; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(1024)); + const formattedSize = (bytes / Math.pow(1024, i)).toFixed(2); + return `${formattedSize} ${sizes[i]}`; +} +export function createStyleSheet(id) { + const style = document.createElement('style'); + style.setAttribute('id', id); + style.setAttribute('rel', 'stylesheet'); + style.setAttribute('type', 'text/css'); + document.head.appendChild(style); + return style; +} diff --git a/web/utils.ts b/web/utils.ts index b407610..88421c6 100644 --- a/web/utils.ts +++ b/web/utils.ts @@ -64,3 +64,22 @@ export function injectCss(href: string): Promise { document.head.appendChild(link); }); } + +export function formatBytes(bytes: number): string { + if (bytes === 0) return '0 Bytes'; + + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(1024)); + const formattedSize = (bytes / Math.pow(1024, i)).toFixed(2); + + return `${formattedSize} ${sizes[i]}`; +} + +export function createStyleSheet(id: string): HTMLStyleElement { + const style = document.createElement('style'); + style.setAttribute('id', id); + style.setAttribute('rel', 'stylesheet'); + style.setAttribute('type', 'text/css'); + document.head.appendChild(style); + return style; +} From c05f5bf55c4b32f26ca5edc0e30946f90995c58d Mon Sep 17 00:00:00 2001 From: Crystian Date: Mon, 23 Sep 2024 15:13:35 +0200 Subject: [PATCH 23/31] pillow minimum version updated --- README.md | 1 + __init__.py | 2 +- core/version.py | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- version | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c694aae..48ad4f0 100644 --- a/README.md +++ b/README.md @@ -514,6 +514,7 @@ You have predefined switches (string, latent, image, conditioning) but you can u ### 1.18.0 (21/09/2024) - HORIZONTAL UI! 🎉 +- Configurable size of monitors on settings menu ### 1.17.0 (21/09/2024) - Settings menu reorganized diff --git a/__init__.py b/__init__.py index 05db9ae..677078d 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ @author: Crystian @title: Crystools @nickname: Crystools -@version: 1.18.1 +@version: 1.18.2 @project: "https://github.com/crystian/ComfyUI-Crystools", @description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia """ diff --git a/core/version.py b/core/version.py index cefde7d..b03ecb2 100644 --- a/core/version.py +++ b/core/version.py @@ -1 +1 @@ -version = "1.18.1" +version = "1.18.2" diff --git a/pyproject.toml b/pyproject.toml index 807a9d2..eba1dd8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-crystools" description = "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." -version = "1.18.1" +version = "1.18.2" license = { file = "LICENSE" } dependencies = ["deepdiff", "torch", "numpy", "Pillow", "pynvml", "py-cpuinfo"] diff --git a/requirements.txt b/requirements.txt index cd1f8a4..d61acb5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ deepdiff torch numpy -Pillow +Pillow>=9.5.0 pynvml py-cpuinfo piexif diff --git a/version b/version index ec6d649..b57fc72 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.18.1 +1.18.2 From 23028b130e580cfcd08b98f8436c5d8993ad567c Mon Sep 17 00:00:00 2001 From: Crystian Date: Tue, 24 Sep 2024 12:55:12 +0200 Subject: [PATCH 24/31] monitors move to comfyui-menu-push --- __init__.py | 2 +- core/version.py | 2 +- pyproject.toml | 2 +- version | 2 +- web/monitor.js | 18 ++++++++++++------ web/monitor.ts | 21 +++++++++++++-------- 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/__init__.py b/__init__.py index 677078d..b5855a2 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ @author: Crystian @title: Crystools @nickname: Crystools -@version: 1.18.2 +@version: 1.18.3 @project: "https://github.com/crystian/ComfyUI-Crystools", @description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia """ diff --git a/core/version.py b/core/version.py index b03ecb2..23fa7e6 100644 --- a/core/version.py +++ b/core/version.py @@ -1 +1 @@ -version = "1.18.2" +version = "1.18.3" diff --git a/pyproject.toml b/pyproject.toml index eba1dd8..98aa9a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-crystools" description = "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." -version = "1.18.2" +version = "1.18.3" license = { file = "LICENSE" } dependencies = ["deepdiff", "torch", "numpy", "Pillow", "pynvml", "py-cpuinfo"] diff --git a/version b/version index b57fc72..b9fb27a 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.18.2 +1.18.3 diff --git a/web/monitor.js b/web/monitor.js index adaaeb0..cd46c14 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -509,6 +509,12 @@ class CrystoolsMonitor { if (document.getElementById('ProgressBarUI')) { document.getElementById('ProgressBarUI').style.display = 'flex'; } + if (parentElement && this.monitorUI.htmlRoot) { + parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); + } + else { + console.error('Crystools: parentElement to move monitors not found!', parentElement); + } break; case NewMenuOptions.Top: case NewMenuOptions.Bottom: @@ -516,14 +522,14 @@ class CrystoolsMonitor { document.getElementById('ProgressBarUI').style.display = 'none'; } parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; + if (parentElement && this.monitorUI.htmlRoot) { + parentElement.appendChild(this.monitorUI.htmlRoot); + } + else { + console.error('Crystools: parentElement to move monitors not found!', parentElement); + } break; } - if (parentElement && this.monitorUI.htmlRoot) { - parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); - } - else { - console.error('Crystools: parentElement to move monitors not found!', parentElement); - } } }); Object.defineProperty(this, "updateAllWidget", { diff --git a/web/monitor.ts b/web/monitor.ts index 3dde734..8a20e59 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -404,6 +404,7 @@ class CrystoolsMonitor { }); }; + // eslint-disable-next-line complexity moveMonitor = (position: NewMenuOptions): void => { let parentElement: Element | null | undefined; @@ -416,7 +417,13 @@ class CrystoolsMonitor { document.getElementById('ProgressBarUI').style.display = 'flex'; } + if (parentElement && this.monitorUI.htmlRoot) { + parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); + } else { + console.error('Crystools: parentElement to move monitors not found!', parentElement); + } break; + case NewMenuOptions.Top: case NewMenuOptions.Bottom: // TODO remove this @@ -425,17 +432,15 @@ class CrystoolsMonitor { document.getElementById('ProgressBarUI').style.display = 'none'; } parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; + + if (parentElement && this.monitorUI.htmlRoot) { + parentElement.appendChild(this.monitorUI.htmlRoot); + } else { + console.error('Crystools: parentElement to move monitors not found!', parentElement); + } break; } - if (parentElement && this.monitorUI.htmlRoot) { - // console.log('moveMonitor1', parentElement); - // console.log('moveMonitor2', this.monitorUI.htmlRoot); - parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); - - } else { - console.error('Crystools: parentElement to move monitors not found!', parentElement); - } }; From 3f71a4cda2dc5eb1f84aea390f318d15e0122430 Mon Sep 17 00:00:00 2001 From: Crystian Date: Wed, 25 Sep 2024 00:32:19 +0200 Subject: [PATCH 25/31] monitor adjusted --- __init__.py | 2 +- core/version.py | 2 +- pyproject.toml | 2 +- version | 2 +- web/monitor.css | 25 ++++++++++++++++--------- web/monitor.js | 9 ++------- web/monitor.ts | 6 +++++- web/monitorUI.js | 6 ++++++ web/progressBar.js | 15 +++++++-------- web/progressBar.ts | 1 + web/progressBarUI.js | 13 ++++++++----- web/progressBarUIBase.js | 19 ++++++++++++++++++- 12 files changed, 67 insertions(+), 35 deletions(-) diff --git a/__init__.py b/__init__.py index b5855a2..04c9f95 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ @author: Crystian @title: Crystools @nickname: Crystools -@version: 1.18.3 +@version: 1.18.4 @project: "https://github.com/crystian/ComfyUI-Crystools", @description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia """ diff --git a/core/version.py b/core/version.py index 23fa7e6..f6b1874 100644 --- a/core/version.py +++ b/core/version.py @@ -1 +1 @@ -version = "1.18.3" +version = "1.18.4" diff --git a/pyproject.toml b/pyproject.toml index 98aa9a3..d3a44ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-crystools" description = "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." -version = "1.18.3" +version = "1.18.4" license = { file = "LICENSE" } dependencies = ["deepdiff", "torch", "numpy", "Pillow", "pynvml", "py-cpuinfo"] diff --git a/version b/version index b9fb27a..a67b05e 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.18.3 +1.18.4 diff --git a/web/monitor.css b/web/monitor.css index 14b4f51..d7383e9 100644 --- a/web/monitor.css +++ b/web/monitor.css @@ -1,3 +1,4 @@ +/* Vertical UI */ .comfy-menu #crystools-root { /*background-color: red;*/ box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.3); @@ -97,35 +98,41 @@ } +.comfyui-queue-button{ + /*width: unset !important;*/ +} +/* Horizontal UI */ .comfyui-menu #crystools-root { /*background-color: red;*/ - display: flex; + /*display: none;*/ flex-direction: row; - flex-shrink: 1; - flex-grow: 100; + flex-grow: 5; justify-content: center; - /*gap: 5px;*/ - /*width: 100%;*/ + /*flex: auto;*/ + flex-shrink: 1; + width: min-content; + min-width: max-content; /*height: 100%;*/ + /* max-width: 40vw;*/ + /* min-width: 10vw;*/ + /*gap: 5px;*/ /*margin: 0 auto;*/ /*align-items: center;*/ /*align-self: center;*/ - min-width: 200px; .crystools-monitor-container { /*background-color: var(--comfy-menu-bg);*/ - /*width: 100%;*/ + width: 100%; cursor: crosshair; /*margin: 4px 0;*/ display: flex; /* by progress bar base */ flex-wrap: wrap; flex-direction: row; justify-content: flex-end; - align-items: center; + /*align-items: center;*/ gap: 5px; /*height: 100%;*/ - /*max-width: 300px;*/ /*min-width: 200px;*/ .crystools-monitor { diff --git a/web/monitor.js b/web/monitor.js index cd46c14..4a64279 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -506,9 +506,6 @@ class CrystoolsMonitor { switch (position) { case NewMenuOptions.Disabled: parentElement = document.getElementById('queue-button'); - if (document.getElementById('ProgressBarUI')) { - document.getElementById('ProgressBarUI').style.display = 'flex'; - } if (parentElement && this.monitorUI.htmlRoot) { parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); } @@ -518,12 +515,10 @@ class CrystoolsMonitor { break; case NewMenuOptions.Top: case NewMenuOptions.Bottom: - if (document.getElementById('ProgressBarUI')) { - document.getElementById('ProgressBarUI').style.display = 'none'; - } + this.monitorUI.htmlRoot?.classList.add('comfyui-button-group'); parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; if (parentElement && this.monitorUI.htmlRoot) { - parentElement.appendChild(this.monitorUI.htmlRoot); + parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); } else { console.error('Crystools: parentElement to move monitors not found!', parentElement); diff --git a/web/monitor.ts b/web/monitor.ts index 8a20e59..f92d7a8 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -431,10 +431,14 @@ class CrystoolsMonitor { // @ts-ignore document.getElementById('ProgressBarUI').style.display = 'none'; } + //comfyui-button-group + this.monitorUI.htmlRoot.classList.add('comfyui-button-group'); + // this.monitorUI.htmlRoot.classList.add('comfyui-menu-mobile-collapse'); parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; if (parentElement && this.monitorUI.htmlRoot) { - parentElement.appendChild(this.monitorUI.htmlRoot); + parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); + // parentElement.appendChild(this.monitorUI.htmlRoot); } else { console.error('Crystools: parentElement to move monitors not found!', parentElement); } diff --git a/web/monitorUI.js b/web/monitorUI.js index 1d8be8d..347345e 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -45,6 +45,12 @@ export class MonitorUI extends ProgressBarUIBase { writable: true, value: currentRate }); + Object.defineProperty(this, "showSection", { + enumerable: true, + configurable: true, + writable: true, + value: showSection + }); Object.defineProperty(this, "lastMonitor", { enumerable: true, configurable: true, diff --git a/web/progressBar.js b/web/progressBar.js index dc14a7f..ea5c071 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -85,15 +85,14 @@ class CrystoolsProgressBar { configurable: true, writable: true, value: () => { - const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - if (newMenu !== this.newMenu) { - this.newMenu = newMenu; - this.progressBarUI.showSection = (this.newMenu === NewMenuOptions.Disabled); - if (this.progressBarUI.showSection) { - this.setup(); + setTimeout(() => { + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; + this.progressBarUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); } - } - this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + }); } }); Object.defineProperty(this, "setup", { diff --git a/web/progressBar.ts b/web/progressBar.ts index 46e77bb..20cac8a 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -58,6 +58,7 @@ class CrystoolsProgressBar { return; } + this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); this.progressBarUI = new ProgressBarUI((this.newMenu === NewMenuOptions.Disabled), this.centerNode); diff --git a/web/progressBarUI.js b/web/progressBarUI.js index d28e485..dc7f821 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -2,6 +2,12 @@ import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export class ProgressBarUI extends ProgressBarUIBase { constructor(showSection, centerNode) { super('queue-button', 'crystools-root', showSection); + Object.defineProperty(this, "showSection", { + enumerable: true, + configurable: true, + writable: true, + value: showSection + }); Object.defineProperty(this, "centerNode", { enumerable: true, configurable: true, @@ -73,10 +79,7 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: (currentStatus, timeStart, currentProgress) => { - if (!this.showSection) { - return; - } - if (!this.progressBar) { + if (!(this.showSection && this.progressBar)) { return; } if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { @@ -111,7 +114,7 @@ export class ProgressBarUI extends ProgressBarUIBase { writable: true, value: (value) => { this.progressBar = value; - this.htmlContainer.style.display = this.progressBar ? 'block' : 'none'; + this.showFullSectionOnDemand(this.progressBar && this.showSection); } }); this.createDOM(); diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js index 871a920..e74e3b6 100644 --- a/web/progressBarUIBase.js +++ b/web/progressBarUIBase.js @@ -65,13 +65,30 @@ export class ProgressBarUIBase { console.error('Crystools: parentElement not found', this.parentId); } } - this.showSection = true; this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); this.htmlContainer.setAttribute('id', this.constructor.name); this.htmlRoot.append(this.htmlContainer); } }); + Object.defineProperty(this, "showFullSection", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + this.showSection = value; + this.htmlContainer.style.display = this.showSection ? 'flex' : 'none'; + } + }); + Object.defineProperty(this, "showFullSectionOnDemand", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + this.htmlContainer.style.display = value ? 'flex' : 'none'; + } + }); this.createRoot(); + this.showFullSection(this.showSection); } } From 348c05d55164d0a021cd37f77ee29a9abc184808 Mon Sep 17 00:00:00 2001 From: Crystian Date: Wed, 25 Sep 2024 01:28:45 +0200 Subject: [PATCH 26/31] visual fixes --- web/monitor.js | 8 ++++---- web/monitor.ts | 26 ++++---------------------- web/monitorUI.d.ts | 3 ++- web/monitorUI.js | 23 ++++++++++++----------- web/monitorUI.ts | 15 ++++++++------- web/progressBar.js | 2 +- web/progressBar.ts | 19 +++++++------------ web/progressBarUI.d.ts | 7 +++++-- web/progressBarUI.js | 33 +++++++++++++++++++++++++-------- web/progressBarUI.ts | 25 +++++++++++++++---------- web/progressBarUIBase.d.ts | 3 +-- web/progressBarUIBase.js | 26 +------------------------- web/progressBarUIBase.ts | 10 +--------- 13 files changed, 86 insertions(+), 114 deletions(-) diff --git a/web/monitor.js b/web/monitor.js index 4a64279..a0a531b 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -551,9 +551,9 @@ class CrystoolsMonitor { configurable: true, writable: true, value: (monitorSettings) => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + if (this.monitorUI) { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + this.monitorUI.showMonitor(monitorSettings, value); } } }); @@ -637,7 +637,7 @@ class CrystoolsMonitor { this.createSettings(); const currentRate = parseFloat(app.ui.settings.getSettingValue(this.settingsRate.id, this.settingsRate.defaultValue)); this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); - this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, (this.newMenu === NewMenuOptions.Disabled)); + this.monitorUI = new MonitorUI(this.monitorCPUElement, this.monitorRAMElement, this.monitorHDDElement, this.monitorGPUSettings, this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate); this.updateDisplay(); this.registerListeners(); } diff --git a/web/monitor.ts b/web/monitor.ts index f92d7a8..1826e85 100644 --- a/web/monitor.ts +++ b/web/monitor.ts @@ -404,19 +404,12 @@ class CrystoolsMonitor { }); }; - // eslint-disable-next-line complexity moveMonitor = (position: NewMenuOptions): void => { let parentElement: Element | null | undefined; switch (position) { case NewMenuOptions.Disabled: parentElement = document.getElementById('queue-button'); - // TODO remove this - if (document.getElementById('ProgressBarUI')) { - // @ts-ignore - document.getElementById('ProgressBarUI').style.display = 'flex'; - - } if (parentElement && this.monitorUI.htmlRoot) { parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); } else { @@ -426,26 +419,16 @@ class CrystoolsMonitor { case NewMenuOptions.Top: case NewMenuOptions.Bottom: - // TODO remove this - if (document.getElementById('ProgressBarUI')) { - // @ts-ignore - document.getElementById('ProgressBarUI').style.display = 'none'; - } - //comfyui-button-group - this.monitorUI.htmlRoot.classList.add('comfyui-button-group'); - // this.monitorUI.htmlRoot.classList.add('comfyui-menu-mobile-collapse'); + this.monitorUI.htmlRoot?.classList.add('comfyui-button-group'); parentElement = document.getElementsByClassName('comfyui-menu-push')[0]; if (parentElement && this.monitorUI.htmlRoot) { parentElement.insertAdjacentElement('afterend', this.monitorUI.htmlRoot); - // parentElement.appendChild(this.monitorUI.htmlRoot); } else { console.error('Crystools: parentElement to move monitors not found!', parentElement); } break; } - - }; updateAllWidget = (): void => { @@ -469,9 +452,9 @@ class CrystoolsMonitor { * @param monitorSettings */ updateWidget = (monitorSettings: TMonitorSettings): void => { - const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); - if (monitorSettings.htmlMonitorRef) { - monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + if (this.monitorUI) { + const value = app.ui.settings.getSettingValue(monitorSettings.id, monitorSettings.defaultValue); + this.monitorUI.showMonitor(monitorSettings, value); } }; @@ -544,7 +527,6 @@ class CrystoolsMonitor { this.monitorVRAMSettings, this.monitorTemperatureSettings, currentRate, - (this.newMenu === NewMenuOptions.Disabled), ); this.updateDisplay(); diff --git a/web/monitorUI.d.ts b/web/monitorUI.d.ts index af5056b..16328fc 100644 --- a/web/monitorUI.d.ts +++ b/web/monitorUI.d.ts @@ -9,7 +9,7 @@ export declare class MonitorUI extends ProgressBarUIBase { private currentRate; lastMonitor: number; styleSheet: HTMLStyleElement; - constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number, showSection: boolean); + constructor(monitorCPUElement: TMonitorSettings, monitorRAMElement: TMonitorSettings, monitorHDDElement: TMonitorSettings, monitorGPUSettings: TMonitorSettings[], monitorVRAMSettings: TMonitorSettings[], monitorTemperatureSettings: TMonitorSettings[], currentRate: number); createDOM: () => void; createDOMGPUMonitor: (monitorSettings?: TMonitorSettings) => void; orderMonitors: () => void; @@ -19,4 +19,5 @@ export declare class MonitorUI extends ProgressBarUIBase { updatedAnimationDuration: (monitorSettings: TMonitorSettings, value: number) => void; createMonitor: (monitorSettings?: TMonitorSettings) => HTMLDivElement; updateMonitorSize: (width: number, height: number) => void; + showMonitor: (monitorSettings: TMonitorSettings, value: boolean) => void; } diff --git a/web/monitorUI.js b/web/monitorUI.js index 347345e..454dc1e 100644 --- a/web/monitorUI.js +++ b/web/monitorUI.js @@ -1,8 +1,8 @@ import { ProgressBarUIBase } from './progressBarUIBase.js'; import { createStyleSheet, formatBytes } from './utils.js'; export class MonitorUI extends ProgressBarUIBase { - constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate, showSection) { - super('queue-button', 'crystools-root', showSection); + constructor(monitorCPUElement, monitorRAMElement, monitorHDDElement, monitorGPUSettings, monitorVRAMSettings, monitorTemperatureSettings, currentRate) { + super('queue-button', 'crystools-root'); Object.defineProperty(this, "monitorCPUElement", { enumerable: true, configurable: true, @@ -45,12 +45,6 @@ export class MonitorUI extends ProgressBarUIBase { writable: true, value: currentRate }); - Object.defineProperty(this, "showSection", { - enumerable: true, - configurable: true, - writable: true, - value: showSection - }); Object.defineProperty(this, "lastMonitor", { enumerable: true, configurable: true, @@ -163,9 +157,6 @@ export class MonitorUI extends ProgressBarUIBase { configurable: true, writable: true, value: (monitorSettings, percent, used, total) => { - if (!this.showSection) { - return; - } if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { return; } @@ -269,6 +260,16 @@ export class MonitorUI extends ProgressBarUIBase { }`; } }); + Object.defineProperty(this, "showMonitor", { + enumerable: true, + configurable: true, + writable: true, + value: (monitorSettings, value) => { + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + } + }); this.createDOM(); this.styleSheet = createStyleSheet('crystools-monitors-size'); } diff --git a/web/monitorUI.ts b/web/monitorUI.ts index cbf66cc..cf50d9c 100644 --- a/web/monitorUI.ts +++ b/web/monitorUI.ts @@ -13,9 +13,8 @@ export class MonitorUI extends ProgressBarUIBase { private monitorVRAMSettings: TMonitorSettings[], private monitorTemperatureSettings: TMonitorSettings[], private currentRate: number, - showSection: boolean, ) { - super('queue-button', 'crystools-root', showSection); + super('queue-button', 'crystools-root'); this.createDOM(); this.styleSheet = createStyleSheet('crystools-monitors-size'); @@ -117,12 +116,7 @@ export class MonitorUI extends ProgressBarUIBase { }); }; - // eslint-disable-next-line complexity updateMonitor = (monitorSettings: TMonitorSettings, percent: number, used?: number, total?: number): void => { - if (!this.showSection) { - return; - } - if (!(monitorSettings.htmlMonitorSliderRef && monitorSettings.htmlMonitorLabelRef)) { return; } @@ -132,6 +126,7 @@ export class MonitorUI extends ProgressBarUIBase { } // console.log('updateMonitor', monitorSettings.id, percent); + const prefix = monitorSettings.monitorTitle ? monitorSettings.monitorTitle + ' - ' : ''; let title = `${Math.floor(percent)}${monitorSettings.symbol}`; let postfix = ''; @@ -222,4 +217,10 @@ export class MonitorUI extends ProgressBarUIBase { height: ${height}px; width: ${width}px; }`; }; + + showMonitor = (monitorSettings: TMonitorSettings, value: boolean): void => { + if (monitorSettings.htmlMonitorRef) { + monitorSettings.htmlMonitorRef.style.display = value ? 'flex' : 'none'; + } + }; } diff --git a/web/progressBar.js b/web/progressBar.js index ea5c071..020c05a 100644 --- a/web/progressBar.js +++ b/web/progressBar.js @@ -89,7 +89,7 @@ class CrystoolsProgressBar { const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); if (newMenu !== this.newMenu) { this.newMenu = newMenu; - this.progressBarUI.showFullSection(this.newMenu === NewMenuOptions.Disabled); + this.progressBarUI.showSection(this.newMenu === NewMenuOptions.Disabled); } this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); }); diff --git a/web/progressBar.ts b/web/progressBar.ts index 20cac8a..989b066 100644 --- a/web/progressBar.ts +++ b/web/progressBar.ts @@ -35,19 +35,15 @@ class CrystoolsProgressBar { }; updateDisplay = (): void => { - const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + setTimeout(() => { + const newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); + if (newMenu !== this.newMenu) { + this.newMenu = newMenu; - if (newMenu !== this.newMenu) { - this.newMenu = newMenu; - - this.progressBarUI.showSection = (this.newMenu === NewMenuOptions.Disabled); - if (this.progressBarUI.showSection) { - this.setup(); + this.progressBarUI.showSection(this.newMenu === NewMenuOptions.Disabled); } - } - // this.progressBarUI.showSection = (this.newMenu !== NewMenuOptions.Disabled); - // this.progressBarUI.htmlContainer.style.display = 'none'; - this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + this.progressBarUI.updateDisplay(this.currentStatus, this.timeStart, this.currentProgress); + }); }; // automatically called by ComfyUI @@ -58,7 +54,6 @@ class CrystoolsProgressBar { return; } - this.newMenu = app.ui.settings.getSettingValue('Comfy.UseNewMenu', 'Disabled'); this.progressBarUI = new ProgressBarUI((this.newMenu === NewMenuOptions.Disabled), this.centerNode); diff --git a/web/progressBarUI.d.ts b/web/progressBarUI.d.ts index 8d2755f..88c82e5 100644 --- a/web/progressBarUI.d.ts +++ b/web/progressBarUI.d.ts @@ -1,14 +1,17 @@ import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export declare class ProgressBarUI extends ProgressBarUIBase { + showSectionFlag: boolean; private centerNode; htmlProgressSliderRef: HTMLDivElement; htmlProgressLabelRef: HTMLDivElement; currentStatus: EStatus; timeStart: number; currentProgress: number; - progressBar: boolean; - constructor(showSection: boolean, centerNode: () => void); + showProgressBarFlag: boolean; + constructor(showSectionFlag: boolean, centerNode: () => void); createDOM: () => void; updateDisplay: (currentStatus: EStatus, timeStart: number, currentProgress: number) => void; + showSection: (value: boolean) => void; showProgressBar: (value: boolean) => void; + private displaySection; } diff --git a/web/progressBarUI.js b/web/progressBarUI.js index dc7f821..238c280 100644 --- a/web/progressBarUI.js +++ b/web/progressBarUI.js @@ -1,12 +1,12 @@ import { EStatus, ProgressBarUIBase } from './progressBarUIBase.js'; export class ProgressBarUI extends ProgressBarUIBase { - constructor(showSection, centerNode) { - super('queue-button', 'crystools-root', showSection); - Object.defineProperty(this, "showSection", { + constructor(showSectionFlag, centerNode) { + super('queue-button', 'crystools-root'); + Object.defineProperty(this, "showSectionFlag", { enumerable: true, configurable: true, writable: true, - value: showSection + value: showSectionFlag }); Object.defineProperty(this, "centerNode", { enumerable: true, @@ -44,7 +44,7 @@ export class ProgressBarUI extends ProgressBarUIBase { writable: true, value: void 0 }); - Object.defineProperty(this, "progressBar", { + Object.defineProperty(this, "showProgressBarFlag", { enumerable: true, configurable: true, writable: true, @@ -79,7 +79,7 @@ export class ProgressBarUI extends ProgressBarUIBase { configurable: true, writable: true, value: (currentStatus, timeStart, currentProgress) => { - if (!(this.showSection && this.progressBar)) { + if (!(this.showSectionFlag && this.showProgressBarFlag)) { return; } if (!(this.htmlProgressLabelRef && this.htmlProgressSliderRef)) { @@ -108,13 +108,30 @@ export class ProgressBarUI extends ProgressBarUIBase { } } }); + Object.defineProperty(this, "showSection", { + enumerable: true, + configurable: true, + writable: true, + value: (value) => { + this.showSectionFlag = value; + this.displaySection(); + } + }); Object.defineProperty(this, "showProgressBar", { enumerable: true, configurable: true, writable: true, value: (value) => { - this.progressBar = value; - this.showFullSectionOnDemand(this.progressBar && this.showSection); + this.showProgressBarFlag = value; + this.displaySection(); + } + }); + Object.defineProperty(this, "displaySection", { + enumerable: true, + configurable: true, + writable: true, + value: () => { + this.htmlContainer.style.display = (this.showSectionFlag && this.showProgressBarFlag) ? 'block' : 'none'; } }); this.createDOM(); diff --git a/web/progressBarUI.ts b/web/progressBarUI.ts index 5e6164e..5337911 100644 --- a/web/progressBarUI.ts +++ b/web/progressBarUI.ts @@ -6,13 +6,13 @@ export class ProgressBarUI extends ProgressBarUIBase { currentStatus: EStatus; timeStart: number; currentProgress: number; - progressBar: boolean; + showProgressBarFlag: boolean; constructor( - showSection: boolean, + public showSectionFlag: boolean, private centerNode: () => void, ) { - super('queue-button', 'crystools-root', showSection); + super('queue-button', 'crystools-root'); this.createDOM(); } @@ -41,11 +41,7 @@ export class ProgressBarUI extends ProgressBarUIBase { // eslint-disable-next-line complexity updateDisplay = (currentStatus: EStatus, timeStart: number, currentProgress: number): void => { - if (!this.showSection) { - return; - } - - if (!this.progressBar) { + if (!(this.showSectionFlag && this.showProgressBarFlag)) { return; } @@ -84,9 +80,18 @@ export class ProgressBarUI extends ProgressBarUIBase { }; + public showSection = (value: boolean): void => { + this.showSectionFlag = value; + this.displaySection(); + }; + // remember it can't have more parameters because it is used on settings automatically public showProgressBar = (value: boolean): void => { - this.progressBar = value; - this.htmlContainer.style.display = this.progressBar ? 'block' : 'none'; + this.showProgressBarFlag = value; + this.displaySection(); + }; + + private displaySection = (): void => { + this.htmlContainer.style.display = (this.showSectionFlag && this.showProgressBarFlag) ? 'block' : 'none'; }; } diff --git a/web/progressBarUIBase.d.ts b/web/progressBarUIBase.d.ts index e71591b..10d29c0 100644 --- a/web/progressBarUIBase.d.ts +++ b/web/progressBarUIBase.d.ts @@ -11,11 +11,10 @@ export declare enum NewMenuOptions { export declare abstract class ProgressBarUIBase { parentId: string; rootId: string; - showSection: boolean; htmlRoot: HTMLElement | null; htmlContainer: HTMLDivElement; protected htmlClassMonitor: string; - protected constructor(parentId: string, rootId: string, showSection: boolean); + protected constructor(parentId: string, rootId: string); private createRoot; abstract createDOM(): void; } diff --git a/web/progressBarUIBase.js b/web/progressBarUIBase.js index e74e3b6..d0ba68d 100644 --- a/web/progressBarUIBase.js +++ b/web/progressBarUIBase.js @@ -11,7 +11,7 @@ export var NewMenuOptions; NewMenuOptions["Bottom"] = "Bottom"; })(NewMenuOptions || (NewMenuOptions = {})); export class ProgressBarUIBase { - constructor(parentId, rootId, showSection) { + constructor(parentId, rootId) { Object.defineProperty(this, "parentId", { enumerable: true, configurable: true, @@ -24,12 +24,6 @@ export class ProgressBarUIBase { writable: true, value: rootId }); - Object.defineProperty(this, "showSection", { - enumerable: true, - configurable: true, - writable: true, - value: showSection - }); Object.defineProperty(this, "htmlRoot", { enumerable: true, configurable: true, @@ -71,24 +65,6 @@ export class ProgressBarUIBase { this.htmlRoot.append(this.htmlContainer); } }); - Object.defineProperty(this, "showFullSection", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - this.showSection = value; - this.htmlContainer.style.display = this.showSection ? 'flex' : 'none'; - } - }); - Object.defineProperty(this, "showFullSectionOnDemand", { - enumerable: true, - configurable: true, - writable: true, - value: (value) => { - this.htmlContainer.style.display = value ? 'flex' : 'none'; - } - }); this.createRoot(); - this.showFullSection(this.showSection); } } diff --git a/web/progressBarUIBase.ts b/web/progressBarUIBase.ts index b1ff7c1..4ac4621 100644 --- a/web/progressBarUIBase.ts +++ b/web/progressBarUIBase.ts @@ -18,10 +18,8 @@ export abstract class ProgressBarUIBase { protected constructor( public parentId: string, public rootId: string, - public showSection: boolean, ) { this.createRoot(); - // this.showFullSection(this.showSection); } private createRoot = (): void => { @@ -39,19 +37,13 @@ export abstract class ProgressBarUIBase { console.error('Crystools: parentElement not found', this.parentId); } } - // TODO remove this - this.showSection = true; + this.htmlContainer = document.createElement('div'); this.htmlContainer.classList.add(this.htmlClassMonitor); this.htmlContainer.setAttribute('id', this.constructor.name); this.htmlRoot.append(this.htmlContainer); }; - // public showFullSection(value: boolean): void { - // this.showSection = value; - // this.htmlContainer.style.display = value ? 'flex' : 'none'; - // } - abstract createDOM(): void; // abstract updateDisplay(currentStatus: EStatus, timeStart: number, currentProgress: number): void; From 20aee9723cc3673734d2053a12e10b9184a58fdf Mon Sep 17 00:00:00 2001 From: Crystian Date: Fri, 27 Sep 2024 02:11:51 +0200 Subject: [PATCH 27/31] remove injectCss by utils from comfyui --- .others/ComfyUI.run.xml | 2 +- web/comfy/scripts.d.ts | 2 ++ web/comfy/scripts.js | 2 ++ web/comfy/scripts.ts | 4 ++++ web/styles.js | 5 ++--- web/styles.ts | 6 ++---- web/utils.d.ts | 1 - web/utils.js | 17 ----------------- web/utils.ts | 21 --------------------- 9 files changed, 13 insertions(+), 47 deletions(-) diff --git a/.others/ComfyUI.run.xml b/.others/ComfyUI.run.xml index 805dbaa..ba4a808 100644 --- a/.others/ComfyUI.run.xml +++ b/.others/ComfyUI.run.xml @@ -15,7 +15,7 @@