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;