feat(ui): add send-prompt-to-workflow button for prompt and negative prompt

- Add sendPromptToWorkflow() and stripLoraTags() exports to uiHelpers.js
- Add send button (paper-plane icon) to recipe modal and showcase hover panel
- Restructure showcase metadata panel layout to match recipe modal style
- Respect strip <lora:> setting before sending
- Uses 'replace' mode (not append) on text-capable workflow nodes
- Add translations for all 10 locales
This commit is contained in:
Will Miao
2026-06-23 21:36:24 +08:00
parent 85da7175bc
commit cd2628a0ee
16 changed files with 237 additions and 37 deletions

View File

@@ -3,7 +3,7 @@
* Media-specific utility functions for showcase components
* (Moved from uiHelpers.js to better organize code)
*/
import { showToast, copyToClipboard, getNSFWLevelName } from '../../../utils/uiHelpers.js';
import { showToast, copyToClipboard, getNSFWLevelName, sendPromptToWorkflow, stripLoraTags } from '../../../utils/uiHelpers.js';
import { state } from '../../../state/index.js';
import { getModelApiClient } from '../../../api/modelApiFactory.js';
import { NSFW_LEVELS, getMatureBlurThreshold } from '../../../utils/constants.js';
@@ -318,6 +318,32 @@ export function initMetadataPanelHandlers(container) {
});
});
// Handle send prompt buttons
const sendBtns = metadataPanel.querySelectorAll('.send-prompt-btn');
sendBtns.forEach(sendBtn => {
const promptIndex = sendBtn.dataset.promptIndex;
const promptElement = wrapper.querySelector(`#prompt-${promptIndex}`);
sendBtn.addEventListener('click', async (e) => {
e.stopPropagation();
if (!promptElement) return;
let promptText = promptElement.textContent || '';
if (!promptText.trim()) {
showToast('toast.recipes.noPromptToSend', {}, 'warning');
return;
}
// Respect strip <lora> setting from global state
if (state.global.settings?.strip_lora_on_copy) {
promptText = stripLoraTags(promptText);
}
sendPromptToWorkflow(promptText);
});
});
// Prevent panel scroll from causing modal scroll
metadataPanel.addEventListener('wheel', (e) => {
const isAtTop = metadataPanel.scrollTop === 0;

View File

@@ -53,12 +53,19 @@ export function generateMetadataPanel(hasParams, hasPrompts, prompt, negativePro
prompt = escapeHtml(prompt);
content += `
<div class="metadata-row prompt-row">
<span class="metadata-label">Prompt:</span>
<div class="param-header">
<span class="metadata-label">Prompt:</span>
<div class="param-actions">
<button class="send-prompt-btn" data-prompt-index="${promptIndex}" title="Send Prompt to Workflow">
<i class="fas fa-paper-plane"></i>
</button>
<button class="copy-prompt-btn" data-prompt-index="${promptIndex}" title="Copy Prompt">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
<div class="metadata-prompt-wrapper">
<div class="metadata-prompt">${prompt}</div>
<button class="copy-prompt-btn" data-prompt-index="${promptIndex}">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
<div class="hidden-prompt" id="prompt-${promptIndex}" style="display:none;">${prompt}</div>
@@ -69,12 +76,19 @@ export function generateMetadataPanel(hasParams, hasPrompts, prompt, negativePro
negativePrompt = escapeHtml(negativePrompt);
content += `
<div class="metadata-row prompt-row">
<span class="metadata-label">Negative Prompt:</span>
<div class="param-header">
<span class="metadata-label">Negative Prompt:</span>
<div class="param-actions">
<button class="send-prompt-btn" data-prompt-index="${negPromptIndex}" title="Send Negative Prompt to Workflow">
<i class="fas fa-paper-plane"></i>
</button>
<button class="copy-prompt-btn" data-prompt-index="${negPromptIndex}" title="Copy Negative Prompt">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
<div class="metadata-prompt-wrapper">
<div class="metadata-prompt">${negativePrompt}</div>
<button class="copy-prompt-btn" data-prompt-index="${negPromptIndex}">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
<div class="hidden-prompt" id="prompt-${negPromptIndex}" style="display:none;">${negativePrompt}</div>