Compare commits

...

6 Commits
1.1.0 ... 1.2.0

Author SHA1 Message Date
Dominik Reh
a782f951a6 Code style fixes 2022-10-12 13:54:04 +02:00
Dominik Reh
fd0d05101a Prompt tag insertion bugfix 2022-10-12 13:53:21 +02:00
Dominik Reh
6fa1d1d041 Load custom colors from config 2022-10-12 13:52:20 +02:00
Dominik Reh
00a12b4e41 Removed duplicate tag entries in e621 2022-10-12 13:50:26 +02:00
Dominik Reh
d88ab906d7 Update README.md 2022-10-12 00:15:03 +02:00
Dominik Reh
4243ebe645 e621 tags
Note: This will break coloring at the moment since e621 uses more tag types than Danbooru. I'll try to implement custom color support soon.
2022-10-12 00:05:12 +02:00
4 changed files with 66159 additions and 21 deletions

View File

@@ -9,6 +9,8 @@ I created this script as a convenience tool since it reduces the need of switchi
You can either download the files manually as described below, or use a pre-packaged version from [Releases](https://github.com/DominikDoom/a1111-sd-webui-tagcomplete/releases).
(Note: e621 tags aren't added to the releases yet since coloring is broken for them at the moment).
### Disclaimer:
This script is definitely not optimized, and it's not very intelligent. The tags are simply recommended based on their natural order in the CSV, which is their respective image count for the default Danbooru tag list. Also, at least for now, neither keyboard selection for tags nor completion for negative or img2img prompt textboxes is supported, and there's no way to turn the feature off from the ui, but I plan to get around to those features eventually.

View File

@@ -118,6 +118,13 @@ const debounce = (func, wait = 300) => {
// Difference function to fix duplicates not being seen as changes in normal filter
function difference(a, b) {
if (a.length == 0) {
return b;
}
if (b.length == 0) {
return a;
}
return [...b.reduce( (acc, v) => acc.set(v, (acc.get(v) || 0) - 1),
a.reduce( (acc, v) => acc.set(v, (acc.get(v) || 0) + 1), new Map() )
)].reduce( (acc, [v, count]) => acc.concat(Array(Math.abs(count)).fill(v)), [] );
@@ -157,11 +164,17 @@ function insertTextAtCursor(text, tagword) {
let promptTextbox = gradioApp().querySelector('#txt2img_prompt > label > textarea');
let cursorPos = promptTextbox.selectionStart;
let sanitizedText = acConfig.replaceUnderscores ? text.replaceAll("_", " ") : text;
let optionalComma = (promptTextbox.value[cursorPos] == ",") ? "" : ", ";
var prompt = promptTextbox.value;
let optionalComma = (prompt[cursorPos] === "," || prompt[cursorPos + tagword.length] === ",") ? "" : ", ";
// Edit prompt text
var prompt = promptTextbox.value;
promptTextbox.value = prompt.substring(0, cursorPos - tagword.length) + sanitizedText + optionalComma + prompt.substring(cursorPos);
let direction = prompt.substring(cursorPos, cursorPos + tagword.length) === tagword ? 1 : -1;
if (direction === 1) {
promptTextbox.value = prompt.substring(0, cursorPos) + sanitizedText + optionalComma + prompt.substring(cursorPos + tagword.length)
} else {
promptTextbox.value = prompt.substring(0, cursorPos - tagword.length) + sanitizedText + optionalComma + prompt.substring(cursorPos)
}
prompt = promptTextbox.value;
// Update cursor position to after the inserted text
@@ -176,20 +189,29 @@ function insertTextAtCursor(text, tagword) {
previousTags = tags;
}
const colors_dark = ["lightblue", "indianred", "unused", "violet", "lightgreen", "orange"];
const colors_light = ["dodgerblue", "firebrick", "unused", "darkorchid", "darkgreen", "darkorange" ]
function addResultsToList(results, tagword) {
let resultsList = gradioApp().querySelector('#autocompleteResultsList');
resultsList.innerHTML = "";
let colors = gradioApp().querySelector('.dark') ? colors_dark : colors_light;
// Find right colors from config
let tagFileName = acConfig.tagFile.split(".")[0];
let tagColors = acConfig.colors;
//let colorIndex = Object.keys(tagColors).findIndex(key => key === tagFileName);
//let colorValues = Object.values(tagColors)[colorIndex];
let mode = gradioApp().querySelector('.dark') ? 0 : 1;
for (let i = 0; i < results.length; i++) {
let result = results[i];
let li = document.createElement("li");
li.innerHTML = result[0];
li.style = `color: ${colors[result[1]]};`;
// Set the color of the tag
let tagType = result[1];
li.style = `color: ${tagColors[tagFileName][tagType][mode]};`;
// Add listener
li.addEventListener("click", function() { insertTextAtCursor(result[0], tagword); });
// Add element to list
resultsList.appendChild(li);
}
}
@@ -212,7 +234,7 @@ tagword = "";
resultCount = 0;
function autocomplete(prompt) {
// Guard for empty prompt
if (prompt.length == 0) {
if (prompt.length === 0) {
hideResults();
return;
}
@@ -223,7 +245,7 @@ function autocomplete(prompt) {
previousTags = tags;
// Guard for no difference / only whitespace remaining
if (diff == undefined || diff.length == 0) {
if (diff === undefined || diff.length === 0) {
hideResults();
return;
}
@@ -231,7 +253,7 @@ function autocomplete(prompt) {
tagword = diff[0]
// Guard for empty tagword
if (tagword == undefined || tagword.length == 0) {
if (tagword === undefined || tagword.length === 0) {
hideResults();
return;
}
@@ -240,7 +262,7 @@ function autocomplete(prompt) {
resultCount = results.length;
// Guard for empty results
if (resultCount == 0) {
if (resultCount === 0) {
hideResults();
return;
}
@@ -257,14 +279,14 @@ function navigateInList(event) {
switch (event.key) {
case "ArrowUp":
if (selectedTag == null) {
if (selectedTag === null) {
selectedTag = resultCount - 1;
} else {
selectedTag = (selectedTag - 1 + resultCount) % resultCount;
}
break;
case "ArrowDown":
if (selectedTag == null) {
if (selectedTag === null) {
selectedTag = 0;
} else {
selectedTag = (selectedTag + 1) % resultCount;
@@ -277,7 +299,7 @@ function navigateInList(event) {
selectedTag = resultCount - 1;
break;
case "Enter":
if (selectedTag != null) {
if (selectedTag !== null) {
insertTextAtCursor(results[selectedTag][0], tagword);
}
break;
@@ -286,7 +308,7 @@ function navigateInList(event) {
break;
}
// Update highlighting
if (selectedTag != null)
if (selectedTag !== null)
updateSelectionStyle(selectedTag);
// Prevent default behavior
@@ -296,12 +318,12 @@ function navigateInList(event) {
onUiUpdate(function(){
// One-time CSV setup
if (acConfig == null) acConfig = JSON.parse(readFile("file/tags/config.json"));
if (allTags.length == 0) allTags = loadCSV();
if (acConfig === null) acConfig = JSON.parse(readFile("file/tags/config.json"));
if (allTags.length === 0) allTags = loadCSV();
let promptTextbox = gradioApp().querySelector('#txt2img_prompt > label > textarea');
if (promptTextbox == null) return;
if (promptTextbox === null) return;
if (gradioApp().querySelector('#autocompleteResults') != null) return;
// Only add listeners once
@@ -317,7 +339,7 @@ onUiUpdate(function(){
// Add focusout event listener
promptTextbox.addEventListener('focusout', debounce(() => hideResults(), 400));
// Add up and down arrow event listener
promptTextbox.addEventListener('keydown', function(e) { navigateInList(e); });
promptTextbox.addEventListener('keydown', (e) => navigateInList(e));

View File

@@ -1,5 +1,25 @@
{
"tagFile": "danbooru.csv",
"maxResults": 5,
"replaceUnderscores": true
}
"replaceUnderscores": true,
"colors": {
"danbooru": {
"0": ["lightblue", "dodgerblue"],
"1": ["indianred", "firebrick"],
"3": ["violet", "darkorchid"],
"4": ["lightgreen", "darkgreen"],
"5": ["orange", "darkorange"]
},
"e621": {
"-1": ["red", "maroon"],
"0": ["lightblue", "dodgerblue"],
"1": ["gold", "goldenrod"],
"3": ["violet", "darkorchid"],
"4": ["lightgreen", "darkgreen"],
"5": ["tomato", "darksalmon"],
"6": ["red", "maroon"],
"7": ["whitesmoke", "black"],
"8": ["seagreen", "darkseagreen"]
}
}
}

66094
tags/e621.csv Normal file

File diff suppressed because it is too large Load Diff