diff --git a/web/js/disableDefaultCharacters.js b/web/js/disableDefaultCharacters.js index b05b031..dda1157 100644 --- a/web/js/disableDefaultCharacters.js +++ b/web/js/disableDefaultCharacters.js @@ -2,7 +2,9 @@ import { SettingUtils } from './sn0w.js'; import { app } from "../../../scripts/app.js"; import { api } from "../../../scripts/api.js"; -function updateSorting() { +const settingUtils = new SettingUtils() + +function updateSorting(graphCanvas) { api.fetchApi(`${SettingUtils.API_PREFIX}/update_characters`, { method: "POST", headers: { @@ -10,7 +12,7 @@ function updateSorting() { } }) setTimeout(() => { - app.refreshComboInNodes(); + settingUtils.refreshComboInSingleNode(graphCanvas, "Character Selector"); }, 50); } @@ -20,7 +22,7 @@ const settingDefinition = { name: "[Sn0w] Disable Default Characters", defaultValue: false, type: "boolean", - onChange: () => updateSorting(), + onChange: () => updateSorting(app), }; let setting; diff --git a/web/js/favouriteCharacter.js b/web/js/favouriteCharacter.js index efb85bb..53af324 100644 --- a/web/js/favouriteCharacter.js +++ b/web/js/favouriteCharacter.js @@ -16,6 +16,7 @@ app.registerExtension({ app.canvas.getNodeMenuOptions = function (node) { const options = original_getNodeMenuOptions.apply(this, arguments); if (node.type === "Character Selector") { + const settingUtils = new SettingUtils() const nullIndex = options.indexOf(null); // Check if the filename is in the existingList @@ -28,7 +29,7 @@ app.registerExtension({ disabled: false, callback: () => { SettingUtils.toggleFavourite(existingList, selectedCharacter, favouriteCharactersId); - app.refreshComboInNodes(); + settingUtils.refreshComboInSingleNode(app, "Character Selector"); } }; diff --git a/web/js/loraContextMenu.js b/web/js/loraContextMenu.js index 79bcf83..7cd0833 100644 --- a/web/js/loraContextMenu.js +++ b/web/js/loraContextMenu.js @@ -45,6 +45,7 @@ app.registerExtension({ app.canvas.getNodeMenuOptions = function (node) { const options = original_getNodeMenuOptions.apply(this, arguments); if (loraLoaders.includes(node.type)) { + const settingUtils = new SettingUtils() const nullIndex = options.indexOf(null); // Check if the filename is in the existingList @@ -59,7 +60,7 @@ app.registerExtension({ disabled: false, callback: () => { SettingUtils.toggleFavourite(existingList, filename, favouriteLoraId); - app.refreshComboInNodes(); + settingUtils.refreshComboInSingleNode(app, node.title); } }; diff --git a/web/js/sn0w.js b/web/js/sn0w.js index 103caff..a8d56cf 100644 --- a/web/js/sn0w.js +++ b/web/js/sn0w.js @@ -296,6 +296,83 @@ export class SettingUtils { } } + async #invokeExtensionsAsync(method, graphCanvas, ...args) { + return await Promise.all( + graphCanvas.extensions.map(async (ext) => { + if (method in ext) { + try { + return await ext[method](...args, graphCanvas); + } catch (error) { + console.error( + `Error calling extension '${ext.name}' method '${method}'`, + { error }, + { extension: ext }, + { args } + ); + } + } + }) + ); + } + + async refreshComboInSingleNode(graphCanvas, nodeName) { + const defs = await api.getNodeDefs(); + + // Find the node definition by name + let nodeDef = null; + for (const def of Object.values(defs)) { + if (def.name === nodeName) { + nodeDef = def; + break; + } + } + + if (!nodeDef) { + throw new Error(`Node definition with name ${nodeName} not found`); + } + + // Find the specific node in the graph by name + let node = null; + for (const graphNode of Object.values(graphCanvas.graph._nodes)) { + if (graphNode.type === nodeDef.name) { + node = graphNode; + break; + } + } + + if (!node) { + throw new Error(`Node with name ${nodeName} not found in the graph`); + } + + for(let nodeNum in graphCanvas.graph._nodes) { + const node = graphCanvas.graph._nodes[nodeNum]; + if (node.title == nodeName) { + const def = defs[node.type]; + + // Allow primitive nodes to handle refresh + node.refreshComboInNode?.(defs); + + if(!def) + continue; + + for(const widgetNum in node.widgets) { + const widget = node.widgets[widgetNum] + if(widget.type == "combo" && def["input"]["required"][widget.name] !== undefined) { + widget.options.values = def["input"]["required"][widget.name][0]; + + if(widget.name != 'image' && !widget.options.values.includes(widget.value)) { + widget.value = widget.options.values[0]; + widget.callback(widget.value); + } + } + } + } + } + + await this.#invokeExtensionsAsync("refreshComboInSingleNodeByName", graphCanvas, defs); + } + + static async addStarsToFavourited(existingList) { const menuEntries = document.querySelectorAll('.litemenu-entry'); const highlightLora = await SettingUtils.getSetting("sn0w.HighlightFavourite"); diff --git a/web/js/sortBySeries.js b/web/js/sortBySeries.js index 6ba1ad1..04b72ca 100644 --- a/web/js/sortBySeries.js +++ b/web/js/sortBySeries.js @@ -2,7 +2,9 @@ import { SettingUtils } from './sn0w.js'; import { app } from "../../../scripts/app.js"; import { api } from "../../../scripts/api.js"; -function updateSorting() { +const settingUtils = new SettingUtils() + +function updateSorting(graphCanvas) { api.fetchApi(`${SettingUtils.API_PREFIX}/update_characters`, { method: "POST", headers: { @@ -10,7 +12,7 @@ function updateSorting() { } }) setTimeout(() => { - app.refreshComboInNodes(); + settingUtils.refreshComboInSingleNode(graphCanvas, "Character Selector"); }, 50); } @@ -20,7 +22,7 @@ const settingDefinition = { name: "[Sn0w] Sort Characters By Series", defaultValue: false, type: "boolean", - onChange: () => updateSorting(), + onChange: () => updateSorting(app), }; let setting;