diff --git a/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html b/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html index 29ebb9197..f5001dba4 100644 --- a/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html +++ b/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html @@ -25,6 +25,12 @@ ? +
Custom
+
+ + +
+ diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index e648809ac..8bb40d059 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -16,6 +16,7 @@ import { user_avatar, getCharacterAvatar, formatCharacterAvatar, + substituteParams, } from '../../../script.js'; import { getApiUrl, getContext, extension_settings, doExtrasFetch, modules, renderExtensionTemplate } from '../../extensions.js'; import { selected_group } from '../../group-chats.js'; @@ -24,6 +25,7 @@ import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.j import { SECRET_KEYS, secret_state } from '../../secrets.js'; import { getNovelUnlimitedImageGeneration, getNovelAnlas, loadNovelSubscriptionData } from '../../nai-settings.js'; import { getMultimodalCaption } from '../shared.js'; +import { registerSlashCommand } from '../../slash-commands.js'; export { MODULE_NAME }; // Wraps a string into monospace font-face span @@ -830,6 +832,16 @@ function onComfyWorkflowChange() { extension_settings.sd.comfy_workflow = $('#sd_comfy_workflow').find(':selected').val(); saveSettingsDebounced(); } +async function changeComfyWorkflow(_, name) { + name = name.replace(/(\.json)?$/i, '.json'); + if ($(`#sd_comfy_workflow > [value="${name}"]`).length > 0) { + extension_settings.sd.comfy_workflow = name; + $('#sd_comfy_workflow').val(extension_settings.sd.comfy_workflow); + saveSettingsDebounced(); + } else { + toastr.error(`ComfyUI Workflow "${name}" does not exist.`); + } +} async function validateAutoUrl() { try { @@ -2180,6 +2192,9 @@ async function generateComfyImage(prompt) { placeholders.forEach(ph => { workflow = workflow.replace(`"%${ph}%"`, JSON.stringify(extension_settings.sd[ph])); }); + (extension_settings.sd.comfy_placeholders ?? []).forEach(ph => { + workflow = workflow.replace(`"%${ph.find}%"`, JSON.stringify(substituteParams(ph.replace))); + }); console.log(`{ "prompt": ${workflow} }`); @@ -2216,6 +2231,50 @@ async function onComfyOpenWorkflowEditorClick() { }; $('#sd_comfy_workflow_editor_name').text(extension_settings.sd.comfy_workflow); $('#sd_comfy_workflow_editor_workflow').val(workflow); + const addPlaceholderDom = (placeholder) => { + const el = $(` +
  • + + "%${placeholder.find}%"
    +
    + +
  • + `); + $('#sd_comfy_workflow_editor_placeholder_list_custom').append(el); + el.find('.sd_comfy_workflow_editor_custom_find').val(placeholder.find); + el.find('.sd_comfy_workflow_editor_custom_find').on('input', function() { + placeholder.find = this.value; + el.find('.sd_comfy_workflow_editor_custom_final').text(`"%${this.value}%"`); + el.attr('data-placeholder', `${this.value}`); + checkPlaceholders(); + saveSettingsDebounced(); + }); + el.find('.sd_comfy_workflow_editor_custom_replace').val(placeholder.replace); + el.find('.sd_comfy_workflow_editor_custom_replace').on('input', function() { + placeholder.replace = this.value; + saveSettingsDebounced(); + }); + el.find('.sd_comfy_workflow_editor_custom_remove').on('click', () => { + el.remove(); + extension_settings.sd.comfy_placeholders.splice(extension_settings.sd.comfy_placeholders.indexOf(placeholder)); + saveSettingsDebounced(); + }); + }; + $('#sd_comfy_workflow_editor_placeholder_add').on('click', () => { + if (!extension_settings.sd.comfy_placeholders) { + extension_settings.sd.comfy_placeholders = []; + } + const placeholder = { + find: '', + replace: '', + }; + extension_settings.sd.comfy_placeholders.push(placeholder); + addPlaceholderDom(placeholder); + saveSettingsDebounced(); + }); + (extension_settings.sd.comfy_placeholders ?? []).forEach(placeholder=>{ + addPlaceholderDom(placeholder); + }); checkPlaceholders(); $('#sd_comfy_workflow_editor_workflow').on('input', checkPlaceholders); if (await popupResult) { @@ -2481,7 +2540,8 @@ $('#sd_dropdown [id]').on('click', function () { }); jQuery(async () => { - getContext().registerSlashCommand('imagine', generatePicture, ['sd', 'img', 'image'], helpString, true, true); + registerSlashCommand('imagine', generatePicture, ['sd', 'img', 'image'], helpString, true, true); + registerSlashCommand('imagine-comfy-workflow', changeComfyWorkflow, ['icw'], '(workflowName) - change the workflow to be used for image generation with ComfyUI, e.g. /imagine-comfy-workflow MyWorkflow') $('#extensions_settings').append(renderExtensionTemplate('stable-diffusion', 'settings', defaultSettings)); $('#sd_source').on('change', onSourceChange); diff --git a/public/scripts/extensions/stable-diffusion/style.css b/public/scripts/extensions/stable-diffusion/style.css index 7b9fdd551..139cf3f09 100644 --- a/public/scripts/extensions/stable-diffusion/style.css +++ b/public/scripts/extensions/stable-diffusion/style.css @@ -82,3 +82,17 @@ .sd_comfy_workflow_editor_placeholder_list>li>.notes-link { cursor: help; } + +.sd_comfy_workflow_editor_placeholder_list input { + font-size: inherit; + margin: 0; +} +.sd_comfy_workflow_editor_custom_remove, #sd_comfy_workflow_editor_placeholder_add { + cursor: pointer; + font-weight: bold; + width: 1em; + opacity: 0.5; + &:hover { + opacity: 1; + } +} diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index 7108a9914..bfd49f7c8 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -1108,7 +1108,7 @@ function printGroupCandidates() { showNavigator: true, showSizeChanger: true, pageSize: Number(localStorage.getItem(storageKey)) || 5, - sizeChangerOptions: [5, 10, 25, 50, 100, 200], + sizeChangerOptions: [5, 10, 25, 50, 100, 200, 500, 1000], afterSizeSelectorChange: function (e) { localStorage.setItem(storageKey, e.target.value); }, @@ -1135,7 +1135,7 @@ function printGroupMembers() { showNavigator: true, showSizeChanger: true, pageSize: Number(localStorage.getItem(storageKey)) || 5, - sizeChangerOptions: [5, 10, 25, 50, 100, 200], + sizeChangerOptions: [5, 10, 25, 50, 100, 200, 500, 1000], afterSizeSelectorChange: function (e) { localStorage.setItem(storageKey, e.target.value); }, diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 1768762db..23ca73a56 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -842,6 +842,36 @@ async function unhideMessageCallback(_, arg) { return ''; } +/** + * Copium for running group actions when the member is offscreen. + * @param {number} chid - character ID + * @param {string} action - one of 'enable', 'disable', 'up', 'down', 'peek', 'remove' + * @returns {void} + */ +function performGroupMemberAction(chid, action) { + const memberSelector = `.group_member[chid="${chid}"]`; + // Do not optimize. Paginator gets recreated on every action + const paginationSelector = '#rm_group_members_pagination'; + const pageSizeSelector = '#rm_group_members_pagination select'; + let wasOffscreen = false; + let paginationValue = null; + let pageValue = null; + + if ($(memberSelector).length === 0) { + wasOffscreen = true; + paginationValue = Number($(pageSizeSelector).val()); + pageValue = $(paginationSelector).pagination('getCurrentPageNum'); + $(pageSizeSelector).val($(pageSizeSelector).find('option').last().val()).trigger('change'); + } + + $(memberSelector).find(`[data-action="${action}"]`).trigger('click'); + + if (wasOffscreen) { + $(pageSizeSelector).val(paginationValue).trigger('change'); + $(paginationSelector).pagination('go', pageValue); + } +} + async function disableGroupMemberCallback(_, arg) { if (!selected_group) { toastr.warning('Cannot run /disable command outside of a group chat.'); @@ -855,7 +885,7 @@ async function disableGroupMemberCallback(_, arg) { return ''; } - $(`.group_member[chid="${chid}"] [data-action="disable"]`).trigger('click'); + performGroupMemberAction(chid, 'disable'); return ''; } @@ -872,7 +902,7 @@ async function enableGroupMemberCallback(_, arg) { return ''; } - $(`.group_member[chid="${chid}"] [data-action="enable"]`).trigger('click'); + performGroupMemberAction(chid, 'enable'); return ''; } @@ -889,7 +919,7 @@ async function moveGroupMemberUpCallback(_, arg) { return ''; } - $(`.group_member[chid="${chid}"] [data-action="up"]`).trigger('click'); + performGroupMemberAction(chid, 'up'); return ''; } @@ -906,7 +936,7 @@ async function moveGroupMemberDownCallback(_, arg) { return ''; } - $(`.group_member[chid="${chid}"] [data-action="down"]`).trigger('click'); + performGroupMemberAction(chid, 'down'); return ''; } @@ -928,7 +958,7 @@ async function peekCallback(_, arg) { return ''; } - $(`.group_member[chid="${chid}"] [data-action="view"]`).trigger('click'); + performGroupMemberAction(chid, 'peek'); return ''; } @@ -950,7 +980,7 @@ async function removeGroupMemberCallback(_, arg) { return ''; } - $(`.group_member[chid="${chid}"] [data-action="remove"]`).trigger('click'); + performGroupMemberAction(chid, 'remove'); return ''; }