| import { app } from "../../scripts/app.js"; |
| import { ComfyDialog, $el } from "../../scripts/ui.js"; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const id = "Comfy.NodeTemplates"; |
|
|
| class ManageTemplates extends ComfyDialog { |
| constructor() { |
| super(); |
| this.element.classList.add("comfy-manage-templates"); |
| this.templates = this.load(); |
| } |
|
|
| createButtons() { |
| const btns = super.createButtons(); |
| btns[0].textContent = "Cancel"; |
| btns.unshift( |
| $el("button", { |
| type: "button", |
| textContent: "Save", |
| onclick: () => this.save(), |
| }) |
| ); |
| return btns; |
| } |
|
|
| load() { |
| const templates = localStorage.getItem(id); |
| if (templates) { |
| return JSON.parse(templates); |
| } else { |
| return []; |
| } |
| } |
|
|
| save() { |
| |
| const inputs = this.element.querySelectorAll("input"); |
| const updated = []; |
|
|
| for (let i = 0; i < inputs.length; i++) { |
| const input = inputs[i]; |
| if (input.parentElement.style.display !== "none") { |
| const t = this.templates[i]; |
| t.name = input.value.trim() || input.getAttribute("data-name"); |
| updated.push(t); |
| } |
| } |
|
|
| this.templates = updated; |
| this.store(); |
| this.close(); |
| } |
|
|
| store() { |
| localStorage.setItem(id, JSON.stringify(this.templates)); |
| } |
|
|
| show() { |
| |
| super.show( |
| $el( |
| "div", |
| { |
| style: { |
| display: "grid", |
| gridTemplateColumns: "1fr auto", |
| gap: "5px", |
| }, |
| }, |
| this.templates.flatMap((t) => { |
| let nameInput; |
| return [ |
| $el( |
| "label", |
| { |
| textContent: "Name: ", |
| }, |
| [ |
| $el("input", { |
| value: t.name, |
| dataset: { name: t.name }, |
| $: (el) => (nameInput = el), |
| }), |
| ] |
| ), |
| $el("button", { |
| textContent: "Delete", |
| style: { |
| fontSize: "12px", |
| color: "red", |
| fontWeight: "normal", |
| }, |
| onclick: (e) => { |
| nameInput.value = ""; |
| e.target.style.display = "none"; |
| e.target.previousElementSibling.style.display = "none"; |
| }, |
| }), |
| ]; |
| }) |
| ) |
| ); |
| } |
| } |
|
|
| app.registerExtension({ |
| name: id, |
| setup() { |
| const manage = new ManageTemplates(); |
|
|
| const clipboardAction = (cb) => { |
| |
| |
| const old = localStorage.getItem("litegrapheditor_clipboard"); |
| cb(); |
| localStorage.setItem("litegrapheditor_clipboard", old); |
| }; |
|
|
| const orig = LGraphCanvas.prototype.getCanvasMenuOptions; |
| LGraphCanvas.prototype.getCanvasMenuOptions = function () { |
| const options = orig.apply(this, arguments); |
|
|
| options.push(null); |
| options.push({ |
| content: `Save Selected as Template`, |
| disabled: !Object.keys(app.canvas.selected_nodes || {}).length, |
| callback: () => { |
| const name = prompt("Enter name"); |
| if (!name || !name.trim()) return; |
|
|
| clipboardAction(() => { |
| app.canvas.copyToClipboard(); |
| manage.templates.push({ |
| name, |
| data: localStorage.getItem("litegrapheditor_clipboard"), |
| }); |
| manage.store(); |
| }); |
| }, |
| }); |
|
|
| |
| const subItems = manage.templates.map((t) => ({ |
| content: t.name, |
| callback: () => { |
| clipboardAction(() => { |
| localStorage.setItem("litegrapheditor_clipboard", t.data); |
| app.canvas.pasteFromClipboard(); |
| }); |
| }, |
| })); |
|
|
| if (subItems.length) { |
| subItems.push(null, { |
| content: "Manage", |
| callback: () => manage.show(), |
| }); |
|
|
| options.push({ |
| content: "Node Templates", |
| submenu: { |
| options: subItems, |
| }, |
| }); |
| } |
|
|
| return options; |
| }; |
| }, |
| }); |
|
|