97 lines
4.3 KiB
JavaScript
97 lines
4.3 KiB
JavaScript
import { app } from '../../scripts/app.js';
|
|
import { api } from '../../scripts/api.js';
|
|
import { createScope, mountTheme } from './ui/core.js';
|
|
import { createColorPicker } from './ui/color-picker.js';
|
|
import { WorkflowClock } from './ui/workflow-clock.js';
|
|
|
|
const clock = new WorkflowClock(app.ui.settings);
|
|
let colorPicker;
|
|
|
|
app.registerExtension({
|
|
name: 'ComfyAssets.KikoWorkflowTimer',
|
|
async init() {
|
|
app.ui.settings.addSetting({
|
|
id: 'kikotools.workflow_timer.color',
|
|
name: '🫶 Workflow Timer: Color',
|
|
type: (name, setter, value) => {
|
|
if (!colorPicker || colorPicker.scope?.signal.aborted) {
|
|
colorPicker = createColorPicker(value, setter, app.ui.settings, 'Timer color');
|
|
}
|
|
colorPicker.onChange = setter;
|
|
return colorPicker;
|
|
},
|
|
defaultValue: '#0877bb',
|
|
tooltip: 'Color of the workflow timer display',
|
|
onChange: () => clock.refresh(),
|
|
});
|
|
app.ui.settings.addSetting({
|
|
id: 'kikotools.workflow_timer.glow',
|
|
name: '🫶 Workflow Timer: Enable Glow',
|
|
type: 'boolean',
|
|
defaultValue: true,
|
|
tooltip: 'Enable the pulsing glow unless reduced motion is preferred',
|
|
onChange: () => clock.refresh(),
|
|
});
|
|
},
|
|
|
|
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
|
if (nodeData.name !== 'KikoWorkflowTimer') return;
|
|
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
|
nodeType.prototype.onNodeCreated = function () {
|
|
const result = onNodeCreated?.apply(this, arguments);
|
|
this.timerScope = createScope();
|
|
this.properties = this.properties || {};
|
|
const container = document.createElement('div');
|
|
container.className = 'ca-tools ca-workflow-timer kiko-timer-container';
|
|
const header = document.createElement('header');
|
|
header.className = 'ca-timer-header';
|
|
const title = document.createElement('h3');
|
|
title.textContent = 'Workflow Timer';
|
|
const brand = document.createElement('span');
|
|
brand.textContent = 'ComfyAssets';
|
|
header.append(title, brand);
|
|
this.timerDisplay = document.createElement('div');
|
|
this.timerDisplay.className = 'kiko-timer-display';
|
|
this.timerDisplay.setAttribute('role', 'timer');
|
|
this.timerDisplay.setAttribute('aria-label', 'Elapsed workflow time');
|
|
this.timerDisplay.setAttribute('aria-live', 'off');
|
|
container.append(header, this.timerDisplay);
|
|
mountTheme(container, app.ui.settings, this.timerScope);
|
|
this.addDOMWidget('kikoTimer', 'Kiko Timer', container, {
|
|
serialize: false, hideOnZoom: false, getMinHeight: () => 90,
|
|
});
|
|
this.setSize([340, 180]);
|
|
clock.registerNode(this);
|
|
this.timerScope.cleanup(() => {
|
|
clock.unregisterNode(this);
|
|
container.remove();
|
|
});
|
|
return result;
|
|
};
|
|
const onRemoved = nodeType.prototype.onRemoved;
|
|
nodeType.prototype.onRemoved = function () {
|
|
this.timerScope.dispose();
|
|
return onRemoved?.apply(this, arguments);
|
|
};
|
|
const onSerialize = nodeType.prototype.onSerialize;
|
|
nodeType.prototype.onSerialize = function (data) {
|
|
const result = onSerialize?.apply(this, arguments);
|
|
data.properties = { ...data.properties, elapsed_time_str: this.properties.elapsed_time_str };
|
|
return result;
|
|
};
|
|
const onConfigure = nodeType.prototype.onConfigure;
|
|
nodeType.prototype.onConfigure = function (data) {
|
|
const result = onConfigure?.apply(this, arguments);
|
|
this.properties = { ...(this.properties || {}), ...(data?.properties || {}) };
|
|
if (this.timerDisplay) clock.renderNode(this);
|
|
return result;
|
|
};
|
|
},
|
|
|
|
setup() {
|
|
api.addEventListener('execution_start', () => clock.start());
|
|
api.addEventListener('executing', ({ detail }) => { if (detail === null) clock.stop(); });
|
|
for (const event of ['execution_error', 'execution_interrupted']) api.addEventListener(event, () => clock.stop());
|
|
},
|
|
});
|