diff --git a/javascript/tagAutocomplete.js b/javascript/tagAutocomplete.js index 9a9b51e..2b34237 100644 --- a/javascript/tagAutocomplete.js +++ b/javascript/tagAutocomplete.js @@ -90,6 +90,10 @@ const autocompleteCSS = ` content: "✨"; margin-right: 2px; } + .acMetaText span.used::after { + content: "🔁"; + margin-right: 2px; + } .acWikiLink { padding: 0.5rem; margin: -0.5rem 0 -0.5rem -0.5rem; @@ -666,6 +670,30 @@ function addResultsToList(textArea, results, tagword, resetList) { let tagColors = TAC_CFG.colorMap; let mode = (document.querySelector(".dark") || gradioApp().querySelector(".dark")) ? 0 : 1; let nextLength = Math.min(results.length, resultCount + TAC_CFG.resultStepLength); + const IS_DAN_OR_E621_TAG_FILE = (tagFileName.toLowerCase().startsWith("danbooru") || tagFileName.toLowerCase().startsWith("e621")); + + const tagCount = {}; + + // Indicate if tag was used before + if (IS_DAN_OR_E621_TAG_FILE) { + const prompt = textArea.value.trim(); + const tags = prompt.replaceAll('\n', ',').split(',').map(tag => tag.trim()).filter(tag => tag); + + const unsanitizedTags = tags.map(tag => { + const weightedTags = [...tag.matchAll(WEIGHT_REGEX)].flat(); + if (weightedTags.length === 2) { + return weightedTags[1]; + } else { + // normal tags + return tag; + } + }).map(tag => tag.replaceAll(" ", "_").replaceAll("\\(", "(").replaceAll("\\)", ")")); + + // Split tags by `,` and count tag + for (const tag of unsanitizedTags) { + tagCount[tag] = tagCount[tag] ? tagCount[tag] + 1 : 1; + } + } for (let i = resultCount; i < nextLength; i++) { let result = results[i]; @@ -734,8 +762,7 @@ function addResultsToList(textArea, results, tagword, resetList) { if ( TAC_CFG.showWikiLinks && result.type === ResultType.tag && - (tagFileName.toLowerCase().startsWith("danbooru") || - tagFileName.toLowerCase().startsWith("e621")) + IS_DAN_OR_E621_TAG_FILE ) { let wikiLink = document.createElement("a"); wikiLink.classList.add("acWikiLink"); @@ -828,7 +855,19 @@ function addResultsToList(textArea, results, tagword, resetList) { // Add small ✨ marker to indicate usage sorting if (result.usageBias) { flexDiv.querySelector(".acMetaText").classList.add("biased"); - flexDiv.title = "✨ Frequent tag. Ctrl/Cmd + click to reset usage count." + flexDiv.title = "✨ Frequent tag. Ctrl/Cmd + click to reset usage count."; + } + + // Add 🔁 to indicate if tag was used before + if (IS_DAN_OR_E621_TAG_FILE && tagCount[result.text]) { + // Fix PR#313#issuecomment-2592551794 + if (!(result.text === tagword && tagCount[result.text] === 1)) { + const textNode = flexDiv.querySelector(".acMetaText"); + const span = document.createElement("span"); + textNode.insertBefore(span, textNode.firstChild); + span.classList.add("used"); + span.title = "🔁 The prompt already contains this tag"; + } } // Check if it's a negative prompt