import { app } from "/scripts/app.js"; const realPath = "extensions/Primere"; const validClasses = ['PrimereVisualCKPT', 'PrimereVisualLORA', 'PrimereVisualEmbedding', 'PrimereVisualHypernetwork', 'PrimereVisualStyle']; let defaultSubdir = 'All'; function createCardElement(checkpoint, container, SelectedModel, ModelType) { let checkpoint_new = checkpoint.replaceAll('\\', '/'); let dotLastIndex = checkpoint_new.lastIndexOf('.'); if (dotLastIndex > 1) { var finalName = checkpoint_new.substring(0, dotLastIndex); } else { var finalName = checkpoint_new; } finalName = finalName.replaceAll(' ', "_"); let previewName = finalName + '.jpg'; console.log(previewName); let pathLastIndex = finalName.lastIndexOf('/'); let ckptName = finalName.substring(pathLastIndex + 1); var card_html = '
' + ckptName.replaceAll('_', " ") + '
'; var imgsrc = realPath + '/images/' + ModelType + '/' + previewName; var missingimgsrc = realPath + '/images/missing.jpg'; var card = document.createElement("div"); card.classList.add('visual-ckpt'); if (SelectedModel === checkpoint) { card.classList.add('visual-ckpt-selected'); } const img = new Image(); img.src = imgsrc; img.onload = () => { const width = img.width; if (width > 0) { card_html += ''; card.innerHTML = card_html; container.appendChild(card); } }; img.onerror = () => { card_html += ''; card.innerHTML = card_html; container.appendChild(card); }; } app.registerExtension({ name: "Primere.VisualMenu", init() { /* Promise.all([ fetch('extensions/Primere/keywords/lora-keyword.txt').then(x => x.text()), fetch('extensions/Primere/keywords/model-keyword.txt').then(x => x.text()) ]).then(([Lora, Model]) => { console.log(Lora); console.log(Model); }); */ let callbackfunct = null; function ModalHandler() { let head = document.getElementsByTagName('HEAD')[0]; let link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = realPath + '/css/visual.css'; head.appendChild(link); let js = document.createElement("script"); js.src = realPath + "/jquery/jquery-1.9.0.min.js"; head.appendChild(js); js.onload = function(e) { $(document).ready(function () { var modal = null; $('body').on("click", 'button.modal-closer', function() { modal = document.getElementById("primere_visual_modal"); modal.setAttribute('style','display: none; width: 60%; height: 70%;') }); $('body').on("click", 'div.primere-modal-content div.visual-ckpt img', function() { var ckptName = $(this).data('ckptname'); modal = document.getElementById("primere_visual_modal"); modal.setAttribute('style','display: none; width: 60%; height: 70%;') apply_modal(ckptName); }); var subdirName ='All'; var filteredCheckpoints = 0; $('body').on("click", 'div.subdirtab button.subdirfilter', function() { $('div.subdirtab input').val(''); subdirName = $(this).data('ckptsubdir'); defaultSubdir = subdirName; var imageContainers = $('div.primere-modal-content div.visual-ckpt'); filteredCheckpoints = 0; $(imageContainers).find('img').each(function (img_index, img_obj) { var ImageCheckpoint = $(img_obj).data('ckptname'); if (subdirName === 'Root') { let isSubdirExist = ImageCheckpoint.lastIndexOf('\\'); if (isSubdirExist > 1 && $(img_obj).parent().closest(".visual-ckpt-selected").length === 0) { $(img_obj).parent().hide(); } else { $(img_obj).parent().show(); filteredCheckpoints++; } } else { if (!ImageCheckpoint.startsWith(subdirName) && subdirName !== 'All' && $(img_obj).parent().closest(".visual-ckpt-selected").length === 0) { $(img_obj).parent().hide(); } else { $(img_obj).parent().show(); filteredCheckpoints++; } } }); $('div#primere_visual_modal div.modal_header label.ckpt-name').text(subdirName); $('div#primere_visual_modal div.modal_header label.ckpt-counter').text(filteredCheckpoints - 1); $('div.subdirtab button.subdirfilter').removeClass("selected_path"); $(this).addClass('selected_path'); $(".visual-ckpt-selected").prependTo(".primere-modal-content"); }); $('body').on("keyup", 'div.subdirtab input', function() { var filter = $(this).val(); var imageContainers = $('div.primere-modal-content div.visual-ckpt'); filteredCheckpoints = 0; $(imageContainers).find('img').each(function (img_index, img_obj) { var ImageCheckpoint = $(img_obj).data('ckptname'); let dotLastIndex = ImageCheckpoint.lastIndexOf('.'); if (dotLastIndex > 1) { var finalFilter = ImageCheckpoint.substring(0, dotLastIndex); } else { var finalFilter = ImageCheckpoint; } if (!ImageCheckpoint.startsWith(subdirName) && subdirName !== 'All' && $(img_obj).parent().closest(".visual-ckpt-selected").length === 0) { $(img_obj).parent().hide(); } else { if (finalFilter.toLowerCase().indexOf(filter.toLowerCase()) >= 0 || $(img_obj).parent().closest(".visual-ckpt-selected").length > 0) { $(img_obj).parent().show(); filteredCheckpoints++; } else { $(img_obj).parent().hide(); } } }); $('div#primere_visual_modal div.modal_header label.ckpt-counter').text(filteredCheckpoints - 1); $(".visual-ckpt-selected").prependTo(".primere-modal-content"); }); $('body').on("click", 'div.subdirtab button.filter_clear', function() { $('div.subdirtab input').val(''); var imageContainers = $('div.primere-modal-content div.visual-ckpt'); filteredCheckpoints = 0; $(imageContainers).find('img').each(function (img_index, img_obj) { var ImageCheckpoint = $(img_obj).data('ckptname'); if (!ImageCheckpoint.startsWith(subdirName) && subdirName !== 'All' && $(img_obj).parent().closest(".visual-ckpt-selected").length === 0) { $(img_obj).parent().hide(); } else { $(img_obj).parent().show(); filteredCheckpoints++; } }); $('div#primere_visual_modal div.modal_header label.ckpt-counter').text(filteredCheckpoints - 1); $(".visual-ckpt-selected").prependTo(".primere-modal-content"); }); }); }; } function apply_modal(Selected) { if (Selected && typeof callbackfunct == 'function') { callbackfunct(Selected); return false; } } function setup_visual_modal(combo_name, AllModels, ShowHidden, SelectedModel, ModelType, node) { var container = null; var modal = null; var modalExist = true; modal = document.getElementById("primere_visual_modal"); if (!modal) { modalExist = false; modal = document.createElement("div"); modal.classList.add("comfy-modal"); modal.setAttribute("id","primere_visual_modal"); modal.innerHTML=''; let subdir_container = document.createElement("div"); subdir_container.classList.add("subdirtab"); let container = document.createElement("div"); container.classList.add("primere-modal-content", "ckpt-container", "ckpt-grid-layout"); modal.appendChild(subdir_container); modal.appendChild(container); document.body.appendChild(modal); } else { $('div#primere_visual_modal div.modal_header h3.visual_modal_title').html(combo_name.replace("_"," ") + ' :: :: '); } container = modal.getElementsByClassName("ckpt-container")[0]; container.innerHTML = ""; var subdirArray = ['All']; for (var checkpoints of AllModels) { let pathLastIndex = checkpoints.lastIndexOf('\\'); let ckptSubdir = checkpoints.substring(0, pathLastIndex); if (ckptSubdir === '') { ckptSubdir = 'Root'; } if (subdirArray.indexOf(ckptSubdir) === -1) { subdirArray.push(ckptSubdir); } } var subdir_tabs = modal.getElementsByClassName("subdirtab")[0]; var menu_html = ''; console.log(node.type + ' - ' + defaultSubdir); for (var subdir of subdirArray) { var addWhiteClass = ''; let firstletter = subdir.charAt(0); var subdirName = subdir; if (firstletter === '.') { subdirName = subdir.substring(1); } if ((firstletter === '.' && ShowHidden === true) || firstletter !== '.') { if (subdirName == 'All') { addWhiteClass = ' selected_path'; } menu_html += ''; } } subdir_tabs.innerHTML = menu_html + ' '; var CKPTElements = 0; for (var checkpoint of AllModels) { let firstletter = checkpoint.charAt(0); if (((firstletter === '.' && ShowHidden === true) || firstletter !== '.') && ((checkpoint.match('^NSFW') && ShowHidden === true) || !checkpoint.match('^NSFW'))) { CKPTElements++; createCardElement(checkpoint, container, SelectedModel, ModelType) } } modal.setAttribute('style','display: block; width: 60%; height: 70%;'); var TimingBase =AllModels.length; var mtimeout = TimingBase * 3; if (modalExist === false) { mtimeout = TimingBase * 18; } setTimeout(function(mtimeout) { $('div#primere_visual_modal div.modal_header label.ckpt-name').text('All'); $('div#primere_visual_modal div.modal_header label.ckpt-counter').text(CKPTElements - 1); $(".visual-ckpt-selected").prependTo(".primere-modal-content"); }, mtimeout); } ModalHandler(); let subdirname = ''; let modaltitle = ''; let nodematch = ''; let isnumeric_end = true; const lcg = LGraphCanvas.prototype.processNodeWidgets; LGraphCanvas.prototype.processNodeWidgets = function(node, pos, event, active_widget) { //console.log(node); if (!validClasses.includes(node.type)) { return lcg.call(this, node, pos, event, active_widget); } if (node.type == 'PrimereVisualCKPT') { subdirname = 'checkpoints'; modaltitle = 'Select checkpoint'; nodematch = '^base_model'; isnumeric_end = false; } if (node.type == 'PrimereVisualLORA') { subdirname = 'loras'; modaltitle = 'Select LoRA'; nodematch = '^lora_'; isnumeric_end = true; } if (node.type == 'PrimereVisualEmbedding') { subdirname = 'embeddings'; modaltitle = 'Select embedding'; nodematch = '^embedding_'; isnumeric_end = true; } if (node.type == 'PrimereVisualHypernetwork') { subdirname = 'hypernetworks'; modaltitle = 'Select hypernetwork'; nodematch = '^hypernetwork_'; isnumeric_end = true; } if (node.type == 'PrimereVisualStyle') { subdirname = 'styles'; modaltitle = 'Select style'; nodematch = '^styles'; isnumeric_end = false; } if (event.type != LiteGraph.pointerevents_method + "down") { return lcg.call(this, node, pos, event, active_widget); } if (!node.widgets || !node.widgets.length || (!this.allow_interaction && !node.flags.allow_interaction)) { return lcg.call(this, node, pos, event, active_widget); } var x = pos[0] - node.pos[0]; var y = pos[1] - node.pos[1]; var width = node.size[0]; var that = this; var ShowHidden = false; var ShowModal = false; for (var p = 0; p < node.widgets.length; ++p) { if (node.widgets[p].name == 'show_hidden') { ShowHidden = node.widgets[p].value; } if (node.widgets[p].name == 'show_modal') { ShowModal = node.widgets[p].value; } } if (ShowModal === false) { return lcg.call(this, node, pos, event, active_widget); } for (var i = 0; i < node.widgets.length; ++i) { var w = node.widgets[i]; if (!w || w.disabled) continue; if (w.type != "combo") continue var widget_height = w.computeSize ? w.computeSize(width)[1] : LiteGraph.NODE_WIDGET_HEIGHT; var widget_width = w.width || width; var widget_name = node.widgets[i].name; if (w != active_widget && (x < 6 || x > widget_width - 12 || y < w.last_y || y > w.last_y + widget_height || w.last_y === undefined)) continue if (w == active_widget || (x > 6 && x < widget_width - 12 && y > w.last_y && y < w.last_y + widget_height)) { var delta = x < 40 ? -1 : x > widget_width - 40 ? 1 : 0; if (delta) continue; if (widget_name.match(nodematch) && $.isNumeric(widget_name.substr(-1)) === isnumeric_end) { var AllModels = node.widgets[i].options.values; var SelectedModel = node.widgets[i].value; callbackfunct = inner_clicked.bind(w); setup_visual_modal(modaltitle, AllModels, ShowHidden, SelectedModel, subdirname, node); function inner_clicked(v, option, event) { inner_value_change(this, v); that.dirty_canvas = true; return false; } function inner_value_change(widget, value) { if (widget.type == "number") { value = Number(value); } widget.value = value; if (widget.options && widget.options.property && node.properties[widget.options.property] !== undefined) { node.setProperty(widget.options.property, value); } if (widget.callback) { widget.callback(widget.value, that, node, pos, event); } } return null; } } } return lcg.call(this, node, pos, event, active_widget); } }, async beforeRegisterNodeDef(nodeType, nodeData, app) { }, });