From 03a6f8111cac28b8ce0b58fa969ff4995a0325c2 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Thu, 15 May 2025 07:01:50 +0800 Subject: [PATCH] Add functionality to copy and send LoRA/Recipe syntax to workflow - Implemented copy functionality for LoRA and Recipe syntax in context menus. - Added options to send LoRA and Recipe to workflow in both append and replace modes. - Updated HTML templates to include new context menu items for sending actions. --- .../components/ContextMenu/LoraContextMenu.js | 33 +++++++++- .../ContextMenu/RecipeContextMenu.js | 60 ++++++++++++++++++- templates/components/context_menu.html | 6 ++ templates/recipes.html | 2 + 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/static/js/components/ContextMenu/LoraContextMenu.js b/static/js/components/ContextMenu/LoraContextMenu.js index 9d72f99f..7991d3b7 100644 --- a/static/js/components/ContextMenu/LoraContextMenu.js +++ b/static/js/components/ContextMenu/LoraContextMenu.js @@ -1,6 +1,6 @@ import { BaseContextMenu } from './BaseContextMenu.js'; import { refreshSingleLoraMetadata, saveModelMetadata } from '../../api/loraApi.js'; -import { showToast, getNSFWLevelName } from '../../utils/uiHelpers.js'; +import { showToast, getNSFWLevelName, copyToClipboard, sendLoraToWorkflow } from '../../utils/uiHelpers.js'; import { NSFW_LEVELS } from '../../utils/constants.js'; import { getStorageItem } from '../../utils/storageHelpers.js'; import { showExcludeModal } from '../../utils/modalUtils.js'; @@ -35,7 +35,16 @@ export class LoraContextMenu extends BaseContextMenu { } break; case 'copyname': - this.currentCard.querySelector('.fa-copy')?.click(); + // Generate and copy LoRA syntax + this.copyLoraSyntax(); + break; + case 'sendappend': + // Send LoRA to workflow (append mode) + this.sendLoraToWorkflow(false); + break; + case 'sendreplace': + // Send LoRA to workflow (replace mode) + this.sendLoraToWorkflow(true); break; case 'preview': this.currentCard.querySelector('.fa-image')?.click(); @@ -58,6 +67,26 @@ export class LoraContextMenu extends BaseContextMenu { } } + // New method to handle copy syntax functionality + copyLoraSyntax() { + const card = this.currentCard; + const usageTips = JSON.parse(card.dataset.usage_tips || '{}'); + const strength = usageTips.strength || 1; + const loraSyntax = ``; + + copyToClipboard(loraSyntax, 'LoRA syntax copied to clipboard'); + } + + // New method to handle send to workflow functionality + sendLoraToWorkflow(replaceMode) { + const card = this.currentCard; + const usageTips = JSON.parse(card.dataset.usage_tips || '{}'); + const strength = usageTips.strength || 1; + const loraSyntax = ``; + + sendLoraToWorkflow(loraSyntax, replaceMode, 'lora'); + } + // NSFW Selector methods from the original context menu initNSFWSelector() { // Close button diff --git a/static/js/components/ContextMenu/RecipeContextMenu.js b/static/js/components/ContextMenu/RecipeContextMenu.js index 77145f65..1a3ca0c2 100644 --- a/static/js/components/ContextMenu/RecipeContextMenu.js +++ b/static/js/components/ContextMenu/RecipeContextMenu.js @@ -1,5 +1,5 @@ import { BaseContextMenu } from './BaseContextMenu.js'; -import { showToast } from '../../utils/uiHelpers.js'; +import { showToast, copyToClipboard, sendLoraToWorkflow } from '../../utils/uiHelpers.js'; import { setSessionItem, removeSessionItem } from '../../utils/storageHelpers.js'; import { state } from '../../state/index.js'; @@ -39,8 +39,16 @@ export class RecipeContextMenu extends BaseContextMenu { this.currentCard.click(); break; case 'copy': - // Copy recipe to clipboard - this.currentCard.querySelector('.fa-copy')?.click(); + // Copy recipe syntax to clipboard + this.copyRecipeSyntax(); + break; + case 'sendappend': + // Send recipe to workflow (append mode) + this.sendRecipeToWorkflow(false); + break; + case 'sendreplace': + // Send recipe to workflow (replace mode) + this.sendRecipeToWorkflow(true); break; case 'share': // Share recipe @@ -61,6 +69,52 @@ export class RecipeContextMenu extends BaseContextMenu { } } + // New method to copy recipe syntax to clipboard + copyRecipeSyntax() { + const recipeId = this.currentCard.dataset.id; + if (!recipeId) { + showToast('Cannot copy recipe: Missing recipe ID', 'error'); + return; + } + + fetch(`/api/recipe/${recipeId}/syntax`) + .then(response => response.json()) + .then(data => { + if (data.success && data.syntax) { + copyToClipboard(data.syntax, 'Recipe syntax copied to clipboard'); + } else { + throw new Error(data.error || 'No syntax returned'); + } + }) + .catch(err => { + console.error('Failed to copy recipe syntax: ', err); + showToast('Failed to copy recipe syntax', 'error'); + }); + } + + // New method to send recipe to workflow + sendRecipeToWorkflow(replaceMode) { + const recipeId = this.currentCard.dataset.id; + if (!recipeId) { + showToast('Cannot send recipe: Missing recipe ID', 'error'); + return; + } + + fetch(`/api/recipe/${recipeId}/syntax`) + .then(response => response.json()) + .then(data => { + if (data.success && data.syntax) { + return sendLoraToWorkflow(data.syntax, replaceMode, 'recipe'); + } else { + throw new Error(data.error || 'No syntax returned'); + } + }) + .catch(err => { + console.error('Failed to send recipe to workflow: ', err); + showToast('Failed to send recipe to workflow', 'error'); + }); + } + // View all LoRAs in the recipe viewRecipeLoRAs(recipeId) { if (!recipeId) { diff --git a/templates/components/context_menu.html b/templates/components/context_menu.html index b58479b9..c60debd1 100644 --- a/templates/components/context_menu.html +++ b/templates/components/context_menu.html @@ -11,6 +11,12 @@
Copy LoRA Syntax
+
+ Send to Workflow (Append) +
+
+ Send to Workflow (Replace) +
Replace Preview
diff --git a/templates/recipes.html b/templates/recipes.html index b6d921c5..e0822b53 100644 --- a/templates/recipes.html +++ b/templates/recipes.html @@ -21,6 +21,8 @@
Share Recipe
Copy Recipe Syntax
+
Send to Workflow (Append)
+
Send to Workflow (Replace)
View All LoRAs
Download Missing LoRAs