Add group mode for TriggerWord Toggle

This commit is contained in:
Will Miao
2025-03-11 11:12:37 +08:00
parent c48da5300e
commit f48b954fb7
3 changed files with 82 additions and 28 deletions

View File

@@ -72,6 +72,7 @@ class LoraManagerLoader:
# Add trigger words to collection
all_trigger_words.extend(trigger_words)
trigger_words_text = ", ".join(all_trigger_words) if all_trigger_words else ""
# use ',, ' to separate trigger words for group mode
trigger_words_text = ",, ".join(all_trigger_words) if all_trigger_words else ""
return (model, clip, trigger_words_text)

View File

@@ -10,7 +10,9 @@ class TriggerWordToggle:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"required": {
"group_mode": ("BOOLEAN", {"default": True}),
},
"optional": {
**FlexibleOptionalInputType(any_type),
"trigger_words": ("STRING", {"default": "", "defaultInput": True}),

View File

@@ -2,6 +2,8 @@ import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import { addTagsWidget } from "./tags_widget.js";
const CONVERTED_TYPE = 'converted-widget'
// TriggerWordToggle extension for ComfyUI
app.registerExtension({
name: "LoraManager.TriggerWordToggle",
@@ -28,13 +30,30 @@ app.registerExtension({
node.tagWidget = result.widget;
// Add hidden widget to store original message
const hiddenWidget = node.addWidget('text', 'orinalMessage', '');
hiddenWidget.type = CONVERTED_TYPE;
hiddenWidget.hidden = true;
hiddenWidget.computeSize = () => [0, -4];
// Restore saved value if exists
if (node.widgets_values && node.widgets_values.length > 0) {
// 0 is input, 1 is tag widget
const savedValue = node.widgets_values[1];
// 0 is group mode, 1 is input, 2 is tag widget, 3 is original message
const savedValue = node.widgets_values[2];
if (savedValue) {
result.widget.value = savedValue;
}
const originalMessage = node.widgets_values[3];
if (originalMessage) {
hiddenWidget.value = originalMessage;
}
}
const groupModeWidget = node.widgets[0];
groupModeWidget.callback = (value) => {
if (node.widgets[3].value) {
this.updateTagsBasedOnMode(node, node.widgets[3].value, value);
}
}
});
}
@@ -48,31 +67,63 @@ app.registerExtension({
return;
}
// Store the original message for mode switching
node.widgets[3].value = message;
if (node.tagWidget) {
// Convert comma-separated message to tag object format
if (typeof message === 'string') {
// Get existing tags to preserve active states
const existingTags = node.tagWidget.value || [];
// Create a map of existing tags and their active states
const existingTagMap = {};
existingTags.forEach(tag => {
existingTagMap[tag.text] = tag.active;
});
// Process the incoming message
const tagArray = message
.split(',')
.map(word => word.trim())
.filter(word => word)
.map(word => ({
text: word,
// Keep previous active state if exists, otherwise default to true
active: existingTagMap[word] !== undefined ? existingTagMap[word] : true
}));
node.tagWidget.value = tagArray;
}
// Parse tags based on current group mode
const groupMode = node.widgets[0] ? node.widgets[0].value : false;
this.updateTagsBasedOnMode(node, message, groupMode);
}
},
// Update tags display based on group mode
updateTagsBasedOnMode(node, message, groupMode) {
if (!node.tagWidget) return;
const existingTags = node.tagWidget.value || [];
const existingTagMap = {};
// Create a map of existing tags and their active states
existingTags.forEach(tag => {
existingTagMap[tag.text] = tag.active;
});
let tagArray = [];
if (groupMode) {
if (message.trim() === '') {
tagArray = [];
}
// Group mode: split by ',,' and treat each group as a single tag
else if (message.includes(',,')) {
const groups = message.split(/,{2,}/); // Match 2 or more consecutive commas
tagArray = groups
.map(group => group.trim())
.filter(group => group)
.map(group => ({
text: group,
active: existingTagMap[group] !== undefined ? existingTagMap[group] : true
}));
} else {
// If no ',,' delimiter, treat the entire message as one group
tagArray = [{
text: message.trim(),
active: existingTagMap[message.trim()] !== undefined ? existingTagMap[message.trim()] : true
}];
}
} else {
// Normal mode: split by commas and treat each word as a separate tag
tagArray = message
.split(',')
.map(word => word.trim())
.filter(word => word)
.map(word => ({
text: word,
active: existingTagMap[word] !== undefined ? existingTagMap[word] : true
}));
}
node.tagWidget.value = tagArray;
}
});