mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 15:15:44 -03:00
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.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { BaseContextMenu } from './BaseContextMenu.js';
|
import { BaseContextMenu } from './BaseContextMenu.js';
|
||||||
import { refreshSingleLoraMetadata, saveModelMetadata } from '../../api/loraApi.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 { NSFW_LEVELS } from '../../utils/constants.js';
|
||||||
import { getStorageItem } from '../../utils/storageHelpers.js';
|
import { getStorageItem } from '../../utils/storageHelpers.js';
|
||||||
import { showExcludeModal } from '../../utils/modalUtils.js';
|
import { showExcludeModal } from '../../utils/modalUtils.js';
|
||||||
@@ -35,7 +35,16 @@ export class LoraContextMenu extends BaseContextMenu {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'copyname':
|
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;
|
break;
|
||||||
case 'preview':
|
case 'preview':
|
||||||
this.currentCard.querySelector('.fa-image')?.click();
|
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 = `<lora:${card.dataset.file_name}:${strength}>`;
|
||||||
|
|
||||||
|
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 = `<lora:${card.dataset.file_name}:${strength}>`;
|
||||||
|
|
||||||
|
sendLoraToWorkflow(loraSyntax, replaceMode, 'lora');
|
||||||
|
}
|
||||||
|
|
||||||
// NSFW Selector methods from the original context menu
|
// NSFW Selector methods from the original context menu
|
||||||
initNSFWSelector() {
|
initNSFWSelector() {
|
||||||
// Close button
|
// Close button
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { BaseContextMenu } from './BaseContextMenu.js';
|
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 { setSessionItem, removeSessionItem } from '../../utils/storageHelpers.js';
|
||||||
import { state } from '../../state/index.js';
|
import { state } from '../../state/index.js';
|
||||||
|
|
||||||
@@ -39,8 +39,16 @@ export class RecipeContextMenu extends BaseContextMenu {
|
|||||||
this.currentCard.click();
|
this.currentCard.click();
|
||||||
break;
|
break;
|
||||||
case 'copy':
|
case 'copy':
|
||||||
// Copy recipe to clipboard
|
// Copy recipe syntax to clipboard
|
||||||
this.currentCard.querySelector('.fa-copy')?.click();
|
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;
|
break;
|
||||||
case 'share':
|
case 'share':
|
||||||
// Share recipe
|
// 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
|
// View all LoRAs in the recipe
|
||||||
viewRecipeLoRAs(recipeId) {
|
viewRecipeLoRAs(recipeId) {
|
||||||
if (!recipeId) {
|
if (!recipeId) {
|
||||||
|
|||||||
@@ -11,6 +11,12 @@
|
|||||||
<div class="context-menu-item" data-action="copyname">
|
<div class="context-menu-item" data-action="copyname">
|
||||||
<i class="fas fa-copy"></i> Copy LoRA Syntax
|
<i class="fas fa-copy"></i> Copy LoRA Syntax
|
||||||
</div>
|
</div>
|
||||||
|
<div class="context-menu-item" data-action="sendappend">
|
||||||
|
<i class="fas fa-paper-plane"></i> Send to Workflow (Append)
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-item" data-action="sendreplace">
|
||||||
|
<i class="fas fa-exchange-alt"></i> Send to Workflow (Replace)
|
||||||
|
</div>
|
||||||
<div class="context-menu-item" data-action="preview">
|
<div class="context-menu-item" data-action="preview">
|
||||||
<i class="fas fa-image"></i> Replace Preview
|
<i class="fas fa-image"></i> Replace Preview
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
<!-- <div class="context-menu-item" data-action="details"><i class="fas fa-info-circle"></i> View Details</div> -->
|
<!-- <div class="context-menu-item" data-action="details"><i class="fas fa-info-circle"></i> View Details</div> -->
|
||||||
<div class="context-menu-item" data-action="share"><i class="fas fa-share-alt"></i> Share Recipe</div>
|
<div class="context-menu-item" data-action="share"><i class="fas fa-share-alt"></i> Share Recipe</div>
|
||||||
<div class="context-menu-item" data-action="copy"><i class="fas fa-copy"></i> Copy Recipe Syntax</div>
|
<div class="context-menu-item" data-action="copy"><i class="fas fa-copy"></i> Copy Recipe Syntax</div>
|
||||||
|
<div class="context-menu-item" data-action="sendappend"><i class="fas fa-paper-plane"></i> Send to Workflow (Append)</div>
|
||||||
|
<div class="context-menu-item" data-action="sendreplace"><i class="fas fa-exchange-alt"></i> Send to Workflow (Replace)</div>
|
||||||
<div class="context-menu-item" data-action="viewloras"><i class="fas fa-layer-group"></i> View All LoRAs</div>
|
<div class="context-menu-item" data-action="viewloras"><i class="fas fa-layer-group"></i> View All LoRAs</div>
|
||||||
<div class="context-menu-item download-missing-item" data-action="download-missing"><i class="fas fa-download"></i> Download Missing LoRAs</div>
|
<div class="context-menu-item download-missing-item" data-action="download-missing"><i class="fas fa-download"></i> Download Missing LoRAs</div>
|
||||||
<div class="context-menu-separator"></div>
|
<div class="context-menu-separator"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user