From f095b3d43a8c3728689378eb1c21239c522abdc5 Mon Sep 17 00:00:00 2001 From: Hapse Date: Tue, 29 Oct 2024 18:17:51 +0100 Subject: [PATCH 01/15] adding a space after period messes with weighting syntax (mouse:1.1) turns into (mouse:1. 1) --- web/prompt_gallery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 0c71a4f..5531de8 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1668,7 +1668,7 @@ class PromptGallery { // Remove any duplicate periods or comma-period combinations text = text.replace(/\.{2,}/g, '.').replace(/,\s*\./g, '.'); // Ensure there's a space after each period or comma, but not at the very end - text = text.replace(/([.,])(?=\S)/g, '$1 ').trim(); + text = text.replace(/([,])(?=\S)/g, '$1 ').trim(); return text; } From fb41427ca783c8d85ddc5cac4d89ff947300d65a Mon Sep 17 00:00:00 2001 From: Hapse Date: Wed, 6 Nov 2024 18:32:02 +0100 Subject: [PATCH 02/15] Added the ability to remove the prompt by clicking the image a 2nd time --- web/prompt_gallery.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 5531de8..9e13e76 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1660,8 +1660,8 @@ class PromptGallery { return imgContainer; } + // Remove leading and trailing commas, spaces, and BREAK◘ cleanText(text) { - // Remove leading and trailing commas, spaces, and BREAK text = text.replace(/^[,\s]+|[,\s]+$/g, ''); // Replace BREAK (case insensitive) with a period, handling various scenarios text = text.replace(/\s*BREAK\s*(?:,\s*)?/gi, '. '); @@ -1681,9 +1681,9 @@ class PromptGallery { // If existing text ends with a period, don't add a comma if (existing.endsWith('.')) { return existing + ' ' + newText; - } else { - return existing + ', ' + newText; } + + return existing + newText; } generateRandomPrompt() { @@ -1774,10 +1774,23 @@ class PromptGallery { } if (targetNode && targetWidget) { - // Combine existing text with new text - let newValue = this.combineTexts(targetWidget.value || "", textToCopy); + let newValue = '' + let replacedExistingText = false + if(targetWidget.value.includes(textToCopy)) + { + console.log('found it') + // If the clicked wildcard prompt is already in the textbox, remove it instead of adding it a 2nd time« + newValue = targetWidget.value.replace(textToCopy,'') + replacedExistingText = true + } + else { + console.log('didnt find it') + // Combine existing text with new text + newValue = this.combineTexts(targetWidget.value || "", textToCopy); + } targetWidget.value = newValue; + if (targetNode.onWidgetChanged) { this.log("Debug: Calling onWidgetChanged"); targetNode.onWidgetChanged(targetWidget.name, targetWidget.value); @@ -1786,7 +1799,10 @@ class PromptGallery { // Mark the canvas as dirty to trigger a redraw app.graph.setDirtyCanvas(true, true); - this.showToast('success', 'Tags Sent!', `Tags for "${imageName}" sent to ${targetNode.title} - ${targetWidget.name}`); + if(replacedExistingText) + this.showToast('success', 'Removed Tags!', `Tags for "${imageName}" removed from ${targetNode.title} - ${targetWidget.name}`); + else + this.showToast('success', 'Tags Sent!', `Tags for "${imageName}" sent to ${targetNode.title} - ${targetWidget.name}`); } else { // Fallback to clipboard navigator.clipboard.writeText(textToCopy).then(() => { From c4c445acb7441a91a749ea3187f2f81df452fb2b Mon Sep 17 00:00:00 2001 From: Hapse Date: Wed, 6 Nov 2024 18:32:54 +0100 Subject: [PATCH 03/15] Removed cleantext --- web/prompt_gallery.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 9e13e76..8efe4a6 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1661,20 +1661,20 @@ class PromptGallery { } // Remove leading and trailing commas, spaces, and BREAK◘ - cleanText(text) { - text = text.replace(/^[,\s]+|[,\s]+$/g, ''); - // Replace BREAK (case insensitive) with a period, handling various scenarios - text = text.replace(/\s*BREAK\s*(?:,\s*)?/gi, '. '); - // Remove any duplicate periods or comma-period combinations - text = text.replace(/\.{2,}/g, '.').replace(/,\s*\./g, '.'); - // Ensure there's a space after each period or comma, but not at the very end - text = text.replace(/([,])(?=\S)/g, '$1 ').trim(); - return text; - } + // cleanText(text) { + // text = text.replace(/^[,\s]+|[,\s]+$/g, ''); + // // Replace BREAK (case insensitive) with a period, handling various scenarios + // text = text.replace(/\s*BREAK\s*(?:,\s*)?/gi, '. '); + // // Remove any duplicate periods or comma-period combinations + // text = text.replace(/\.{2,}/g, '.').replace(/,\s*\./g, '.'); + // // Ensure there's a space after each period or comma, but not at the very end + // text = text.replace(/([,])(?=\S)/g, '$1 ').trim(); + // return text; + // } combineTexts(existing, newText) { - existing = this.cleanText(existing); - newText = this.cleanText(newText); + // existing = this.cleanText(existing); + // newText = this.cleanText(newText); if (!existing) return newText; @@ -1711,10 +1711,10 @@ class PromptGallery { const randomImage = categoryImages[Math.floor(Math.random() * categoryImages.length)]; this.log("Random image selected:", randomImage); - const cleanedTags = this.cleanText(randomImage.tags); - this.log("Cleaned tags:", cleanedTags); + // const cleanedTags = this.cleanText(randomImage.tags); + // this.log("Cleaned tags:", cleanedTags); - randomPrompt = this.combineTexts(randomPrompt, cleanedTags); + randomPrompt = this.combineTexts(randomPrompt, randomImage.tags); this.log("Current random prompt:", randomPrompt); } else { this.log(`No images found for category: ${category}`); @@ -1740,7 +1740,7 @@ class PromptGallery { textToCopy = String(textToCopy).trim(); // Clean the new text - textToCopy = this.cleanText(textToCopy); + // textToCopy = this.cleanText(textToCopy); const useSelectedNode = document.getElementById("use-selected-node").checked; const targetNodeDropdown = document.getElementById("target-node-dropdown"); From f10b0c3cc842b9ff3826831d291cc73ee264503b Mon Sep 17 00:00:00 2001 From: Hapse Date: Wed, 6 Nov 2024 18:34:13 +0100 Subject: [PATCH 04/15] clean up --- web/prompt_gallery.js | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 8efe4a6..2340192 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1660,22 +1660,7 @@ class PromptGallery { return imgContainer; } - // Remove leading and trailing commas, spaces, and BREAK◘ - // cleanText(text) { - // text = text.replace(/^[,\s]+|[,\s]+$/g, ''); - // // Replace BREAK (case insensitive) with a period, handling various scenarios - // text = text.replace(/\s*BREAK\s*(?:,\s*)?/gi, '. '); - // // Remove any duplicate periods or comma-period combinations - // text = text.replace(/\.{2,}/g, '.').replace(/,\s*\./g, '.'); - // // Ensure there's a space after each period or comma, but not at the very end - // text = text.replace(/([,])(?=\S)/g, '$1 ').trim(); - // return text; - // } - combineTexts(existing, newText) { - // existing = this.cleanText(existing); - // newText = this.cleanText(newText); - if (!existing) return newText; // If existing text ends with a period, don't add a comma @@ -1711,9 +1696,6 @@ class PromptGallery { const randomImage = categoryImages[Math.floor(Math.random() * categoryImages.length)]; this.log("Random image selected:", randomImage); - // const cleanedTags = this.cleanText(randomImage.tags); - // this.log("Cleaned tags:", cleanedTags); - randomPrompt = this.combineTexts(randomPrompt, randomImage.tags); this.log("Current random prompt:", randomPrompt); } else { @@ -1738,9 +1720,6 @@ class PromptGallery { } textToCopy = String(textToCopy).trim(); - - // Clean the new text - // textToCopy = this.cleanText(textToCopy); const useSelectedNode = document.getElementById("use-selected-node").checked; const targetNodeDropdown = document.getElementById("target-node-dropdown"); @@ -1778,13 +1757,11 @@ class PromptGallery { let replacedExistingText = false if(targetWidget.value.includes(textToCopy)) { - console.log('found it') // If the clicked wildcard prompt is already in the textbox, remove it instead of adding it a 2nd time« newValue = targetWidget.value.replace(textToCopy,'') replacedExistingText = true } else { - console.log('didnt find it') // Combine existing text with new text newValue = this.combineTexts(targetWidget.value || "", textToCopy); } From 06d348557c1174d10738d1080eef4c4bab61668c Mon Sep 17 00:00:00 2001 From: qudgh Date: Wed, 27 Nov 2024 16:06:01 +0900 Subject: [PATCH 05/15] Updated to more intuitive sorting --- web/prompt_gallery.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 0c71a4f..0d3df5d 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1123,14 +1123,20 @@ class PromptGallery { }); //this.log("Sorted Categories:", categories); + + // more intuitive sorting + // ex) [image1, image10, image2] -> [image1, image2, image10] + function naturalSort(a, b) { + return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }); + } for (const category of categories) { //this.log(`Processing category: ${category}`); const images = groupedImages[category]; const sortedImages = [...images].sort((a, b) => { return this.sortAscending - ? a.name.localeCompare(b.name) - : b.name.localeCompare(a.name); + ? naturalSort(a.name, b.name) + : naturalSort(b.name, a.name); }); const accordionSection = this.createAccordionSection(category, sortedImages); this.accordion.appendChild(accordionSection); From 0517f9f8e54cf013ada3e13ca1f0db0aa41b74d9 Mon Sep 17 00:00:00 2001 From: qudgh Date: Wed, 27 Nov 2024 16:16:11 +0900 Subject: [PATCH 06/15] Optimizing: lazy loading images --- web/prompt_gallery.js | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 0d3df5d..e81e814 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -33,6 +33,7 @@ class PromptGallery { this.missingFiles = new Set(); this.librariesLoadPromise = null; this.isDebugMode = false; + this.imagePaths = {}; // Initialize category order from YAML files @@ -1622,7 +1623,7 @@ class PromptGallery { }); const img = $el("img", { - src: this.missingFiles.has(image.path) ? this.placeholderImageUrl : image.path, + src: this.placeholderImageUrl, alt: image.name, style: { width: `${this.maxThumbnailSize}px`, @@ -1630,17 +1631,20 @@ class PromptGallery { objectFit: "cover", borderRadius: "5px" }, - onerror: () => { - if (!this.missingFiles.has(image.path)) { - this.missingFiles.add(image.path); - img.src = this.placeholderImageUrl; - } else { + // onerror: () => { + // if (!this.missingFiles.has(image.path)) { + // this.missingFiles.add(image.path); + // img.src = this.placeholderImageUrl; + // } else { // If even the placeholder fails to load, hide the image - img.style.display = 'none'; - console.error("Failed to load placeholder image for:", image.name); - } - } + // img.style.display = 'none'; + // console.error("Failed to load placeholder image for:", image.name); + // } + // } }); + + this.imagePaths[image.name] = image.path; // image path set + this.observeImage(img); // lazy loading imgContainer.appendChild(img); @@ -1665,6 +1669,24 @@ class PromptGallery { return imgContainer; } + + // Intersection Observer + observeImage(img) { + if (!this.imageObserver) { + this.imageObserver = new IntersectionObserver( + (entries, observer) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const img = entry.target; + img.src = this.imagePaths[img.alt]; + observer.unobserve(img); + } + }); + } + ); + } + this.imageObserver.observe(img); + } cleanText(text) { // Remove leading and trailing commas, spaces, and BREAK From 97fcfa1aae4eb76a74c1add3666a85420f3751fd Mon Sep 17 00:00:00 2001 From: qudgh Date: Wed, 27 Nov 2024 16:28:00 +0900 Subject: [PATCH 07/15] Optimizing: To fetch YAML data only once --- web/prompt_gallery.js | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index e81e814..74d32e8 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -34,7 +34,7 @@ class PromptGallery { this.librariesLoadPromise = null; this.isDebugMode = false; this.imagePaths = {}; - + this.fetchContent = {}; //fetching once // Initialize category order from YAML files this.yamlFiles.forEach(file => { @@ -275,7 +275,7 @@ class PromptGallery { ///NEW DATA STRUCTURE STUFF async loadLibraries() { - if (!this.librariesLoadPromise) { + if (this.librariesLoadPromise === null) { this.librariesLoadPromise = this._loadLibrariesInternal(); } return this.librariesLoadPromise; @@ -378,8 +378,8 @@ class PromptGallery { for (const file of this.yamlFiles) { try { - const response = await fetch(`${this.baseUrl}/prompt_gallery/yaml?filename=${file.name}`); - if (!response.ok) { + const result = await this.fetchYamlContent(file.name); + if (!result) { this.log(`YAML file not found: ${file.name}`); return false; } @@ -1130,12 +1130,12 @@ class PromptGallery { function naturalSort(a, b) { return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }); } - + for (const category of categories) { //this.log(`Processing category: ${category}`); const images = groupedImages[category]; const sortedImages = [...images].sort((a, b) => { - return this.sortAscending + return this.sortAscending ? naturalSort(a.name, b.name) : naturalSort(b.name, a.name); }); @@ -1338,17 +1338,26 @@ class PromptGallery { if (this.missingFiles.has(filename)) { return null; } - const response = await fetch(`${this.baseUrl}/prompt_gallery/yaml?filename=${filename}`); - if (response.status === 404) { - this.missingFiles.add(filename); - return null; - } - if (!response.ok) { - console.warn(`Failed to fetch YAML file ${filename}: ${response.statusText}`); - return null; + if (this.fetchContent[filename]) { + return this.fetchContent[filename]; } - const content = await response.text(); - return content.trim() === "" ? null : content; + this.fetchContent[filename] = fetch(`${this.baseUrl}/prompt_gallery/yaml?filename=${filename}`) + .then((res) => { + if (res.status === 404) { + this.missingFiles.add(filename); + return null; + } + if (!res.ok) { + console.warn(`Failed to fetch YAML file ${filename}: ${res.statusText}`); + return null; + } + return res.text(); + }) + .catch((error) => { + console.error('Error fetching data:', error); + delete this.fetchContent[filename]; + }); + return this.fetchContent[filename]; } From f12a18010e9694a4de316c25402fb34e04274bbe Mon Sep 17 00:00:00 2001 From: qudgh Date: Wed, 27 Nov 2024 16:32:22 +0900 Subject: [PATCH 08/15] Optimizing: Use browser cache for image loading --- __init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index a616c5d..82afd39 100644 --- a/__init__.py +++ b/__init__.py @@ -38,7 +38,7 @@ async def view_image(request): content_type = 'application/octet-stream' return web.Response(body=content, content_type=content_type, - headers={"Content-Disposition": f"filename=\"{filename}{ext}\""}) + headers={"Content-Disposition": f"filename=\"{filename}{ext}\"", "Cache-Control": "max-age=31536000"}) # print(f"[Prompt Gallery] Image not found: {os.path.join(base_path, filename)}") - turned off for spam reasons return web.Response(status=404) From c97660d2c995857d818e88abde723285e851e6c6 Mon Sep 17 00:00:00 2001 From: NLJ Date: Wed, 11 Dec 2024 14:53:42 +0100 Subject: [PATCH 09/15] this and that --- promptImages/promptGallery_libraries.json | 7 +++++++ web/prompt_gallery.js | 11 ++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/promptImages/promptGallery_libraries.json b/promptImages/promptGallery_libraries.json index 1a14397..8ace115 100644 --- a/promptImages/promptGallery_libraries.json +++ b/promptImages/promptGallery_libraries.json @@ -67,6 +67,13 @@ "skipLevels": 0, "sections": null, "order": 10 + }, + { + "name": "Danbooru-styles.yaml", + "type": "styles", + "skipLevels": 0, + "sections": null, + "order": 11 } ] } \ No newline at end of file diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 2340192..eb2ce9c 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -295,6 +295,7 @@ class PromptGallery { } this.categories = this.yamlFiles.map(file => file.type); + console.log(this.categories); this.log("Categories set:", this.categories); this.log("Loaded YAML Files:", JSON.stringify(this.yamlFiles, null, 2)); @@ -1347,6 +1348,7 @@ class PromptGallery { parseYamlForImages(yamlContent, type, skipLevels, sections = null, pathAdjustment = null, ignoreKey = null) { const lines = yamlContent.split('\n'); + const baseFolder = lines[0].slice(0, -1); const stack = []; const images = []; @@ -1365,8 +1367,10 @@ class PromptGallery { const nextLine = lines[index + 1]; if (nextLine && nextLine.trim().startsWith('-')) { let path = stack.slice(skipLevels, -1).map(item => item.key).join('/'); - path = path.replace(/^ponyxl\//, ''); // Remove any duplicate 'ponyxl' in the path - + // console.log(path) + // path = path.replace(/^ponyxl\//, ''); // Remove any duplicate 'ponyxl' in the path + + const tags = nextLine.trim().substring(1).trim(); // Skip empty tags or tags that are just a space @@ -1388,7 +1392,8 @@ class PromptGallery { } const imageFilename = `${key}`; - const subfolderPath = `ponyxl/${path}`; + // const subfolderPath = `${baseFolder}/${path}`; + const subfolderPath = path; const imageUrl = `${this.baseUrl}/prompt_gallery/image?filename=${encodeURIComponent(imageFilename)}&subfolder=${encodeURIComponent(subfolderPath)}`; // Get the immediate parent category (one level up) From 701a7cd906abd7bb761e396a3d2c2b94d421edba Mon Sep 17 00:00:00 2001 From: NLJ Date: Mon, 16 Dec 2024 01:38:00 +0100 Subject: [PATCH 10/15] sections --- web/prompt_gallery.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index eb2ce9c..a8a1acb 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1402,7 +1402,9 @@ class PromptGallery { const image = { name: key, path: imageUrl, tags: tags, type: type, subcategory: immediateParent }; + if (sections) { + console.log(sections) for (const [sectionKey, sectionName] of Object.entries(sections)) { if (path.includes(sectionKey)) { image.section = sectionName; @@ -1636,7 +1638,7 @@ class PromptGallery { } else { // If even the placeholder fails to load, hide the image img.style.display = 'none'; - console.error("Failed to load placeholder image for:", image.name); + // console.error("Failed to load placeholder image for:", image.name); } } }); From 70974fb3a868b4fe57769a024517d18324a2c2db Mon Sep 17 00:00:00 2001 From: NLJ Date: Mon, 16 Dec 2024 14:48:38 +0100 Subject: [PATCH 11/15] fixed sections --- web/prompt_gallery.js | 63 ++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index a8a1acb..38fe692 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -45,16 +45,16 @@ class PromptGallery { }); // Initialize Female Body sub-categories - const femaleBodyFile = this.yamlFiles.find(file => file.type === "Female Body"); - if (femaleBodyFile && femaleBodyFile.sections) { - Object.values(femaleBodyFile.sections).forEach((subCategory, index) => { - const settingId = `Prompt Gallery.Category Order.FemaleBody_${subCategory}`; - const currentValue = this.app.ui.settings.getSettingValue(settingId, null); - if (currentValue === null) { - this.app.ui.settings.setSettingValue(settingId, femaleBodyFile.order + index + 1); - } - }); - } + // const femaleBodyFile = this.yamlFiles.find(file => file.type === "Female Body"); + // if (femaleBodyFile && femaleBodyFile.sections) { + // Object.values(femaleBodyFile.sections).forEach((subCategory, index) => { + // const settingId = `Prompt Gallery.Category Order.FemaleBody_${subCategory}`; + // const currentValue = this.app.ui.settings.getSettingValue(settingId, null); + // if (currentValue === null) { + // this.app.ui.settings.setSettingValue(settingId, femaleBodyFile.order + index + 1); + // } + // }); + // } this.updateCategoryOrder(); @@ -1345,10 +1345,25 @@ class PromptGallery { return content.trim() === "" ? null : content; } + /** + * + * @param {*} yamlContent + * @param {*} type Section title + * @param {*} skipLevels Skip folder in thumbnails + * @param {*} sections + * @param {*} pathAdjustment + * @param {*} ignoreKey + */ + parseYAMLToJson(yamlContent, type, skipLevels, sections = null, pathAdjustment = null, ignoreKey = null) { + + } parseYamlForImages(yamlContent, type, skipLevels, sections = null, pathAdjustment = null, ignoreKey = null) { + console.log('-----') + // console.log(type + ' ' + sections) + const lines = yamlContent.split('\n'); - const baseFolder = lines[0].slice(0, -1); + // const baseFolder = lines[0].slice(0, -1); const stack = []; const images = []; @@ -1393,24 +1408,28 @@ class PromptGallery { const imageFilename = `${key}`; // const subfolderPath = `${baseFolder}/${path}`; - const subfolderPath = path; - const imageUrl = `${this.baseUrl}/prompt_gallery/image?filename=${encodeURIComponent(imageFilename)}&subfolder=${encodeURIComponent(subfolderPath)}`; + // const subfolderPath = path; + const imageUrl = `${this.baseUrl}/prompt_gallery/image?filename=${encodeURIComponent(imageFilename)}&subfolder=${encodeURIComponent(path)}`; // Get the immediate parent category (one level up) const pathParts = path.split('/'); + // console.log(pathParts) const immediateParent = pathParts[pathParts.length - 1]; const image = { name: key, path: imageUrl, tags: tags, type: type, subcategory: immediateParent }; - + // console.log(sections[pathParts[pathParts.length - 1]]) if (sections) { - console.log(sections) - for (const [sectionKey, sectionName] of Object.entries(sections)) { - if (path.includes(sectionKey)) { - image.section = sectionName; - break; - } - } + image.section = sections[pathParts[pathParts.length - 1]]; + // console.log(sections) + // for (const [sectionKey, sectionName] of Object.entries(sections)) { + // console.log(sectionKey + ' ' + sectionName) + // if (path.includes(sectionKey)) { + // image.section = sectionName; + // console.log(sectionKey + ' ' + sectionName + ' ' + path) + // break; + // } + // } } // Special handling for generate_random items in Stereotypes (other_persona.yaml) @@ -1638,7 +1657,7 @@ class PromptGallery { } else { // If even the placeholder fails to load, hide the image img.style.display = 'none'; - // console.error("Failed to load placeholder image for:", image.name); + console.error("Failed to load placeholder image for:", image.name); } } }); From 2879591fbdb24aaa62eade071b806f9e001ccd90 Mon Sep 17 00:00:00 2001 From: NLJ Date: Mon, 16 Dec 2024 15:10:37 +0100 Subject: [PATCH 12/15] if the last character isnt a comma, add one --- web/prompt_gallery.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 38fe692..faba8e9 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -817,7 +817,7 @@ class PromptGallery { } async ensureFileExists(filename) { - const maxAttempts = 10; + const maxAttempts = 1; const delayMs = 500; for (let attempt = 0; attempt < maxAttempts; attempt++) { @@ -1690,11 +1690,15 @@ class PromptGallery { if (!existing) return newText; // If existing text ends with a period, don't add a comma - if (existing.endsWith('.')) { - return existing + ' ' + newText; - } + // if (existing.endsWith('.')) { + // return existing + ' ' + newText; + // } + + //if the last character isnt a comma, add one + if(newText.slice(-1) != ',') + return existing + newText + ','; - return existing + newText; + return existing + newText } generateRandomPrompt() { From 6eaf5c91e31733ce24fb3f79a85679e140d657a1 Mon Sep 17 00:00:00 2001 From: NLJ Date: Mon, 16 Dec 2024 15:15:39 +0100 Subject: [PATCH 13/15] fix comma --- web/prompt_gallery.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index faba8e9..5049565 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1787,8 +1787,10 @@ class PromptGallery { let replacedExistingText = false if(targetWidget.value.includes(textToCopy)) { - // If the clicked wildcard prompt is already in the textbox, remove it instead of adding it a 2nd time« + // If the clicked wildcard prompt is already in the textbox, remove it instead of adding it a 2nd time newValue = targetWidget.value.replace(textToCopy,'') + newValue = targetWidget.value.replace(',,',', ') + newValue = targetWidget.value.replace(', ,',', ') replacedExistingText = true } else { From fec51efb7f3c0c097e7739934c6eb164bf3573f5 Mon Sep 17 00:00:00 2001 From: NLJ Date: Mon, 16 Dec 2024 15:20:00 +0100 Subject: [PATCH 14/15] fix error --- web/prompt_gallery.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index 5049565..d3e2bd0 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -1788,9 +1788,7 @@ class PromptGallery { if(targetWidget.value.includes(textToCopy)) { // If the clicked wildcard prompt is already in the textbox, remove it instead of adding it a 2nd time - newValue = targetWidget.value.replace(textToCopy,'') - newValue = targetWidget.value.replace(',,',', ') - newValue = targetWidget.value.replace(', ,',', ') + newValue = targetWidget.value.replace(textToCopy,'').replace(',,',', ').replace(', ,',', ') replacedExistingText = true } else { From 9c383d9cff6ae4604f86679f635671e6f52964fc Mon Sep 17 00:00:00 2001 From: NLJ Date: Sat, 4 Jan 2025 01:26:26 +0100 Subject: [PATCH 15/15] the ability to turn toasts on or off --- web/prompt_gallery.js | 54 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/web/prompt_gallery.js b/web/prompt_gallery.js index d3e2bd0..a66320e 100644 --- a/web/prompt_gallery.js +++ b/web/prompt_gallery.js @@ -33,6 +33,7 @@ class PromptGallery { this.missingFiles = new Set(); this.librariesLoadPromise = null; this.isDebugMode = false; + this.toastEnabled = this.createEnableToastsCheckbox(); // Initialize category order from YAML files @@ -74,7 +75,8 @@ class PromptGallery { marginRight: "10px" } }, [this.targetNodeDropdown]), - this.useSelectedNodeCheckbox + this.useSelectedNodeCheckbox, + this.toastEnabled ]); this.element = $el("div.prompt-gallery-popup", [ @@ -163,6 +165,41 @@ class PromptGallery { return container; } + createEnableToastsCheckbox() { + const container = $el("div", { + style: { + display: "flex", + alignItems: "center", + marginLeft: "10px", + whiteSpace: "nowrap" + }, + title: "Enable or disable Toasts." + }); + + const checkbox = $el("input", { + type: "checkbox", + id: "enable-toasts", + style: { + marginRight: "5px" + } + }); + + const label = $el("div", { + style: { + fontSize: "12px", + lineHeight: "1", + textAlign: "center" + } + }); + + label.innerHTML = "Enable
Toasts"; + + container.appendChild(checkbox); + container.appendChild(label); + + return container; + } + createRandomPromptButton() { return $el("button", { className: "random-prompt-button", @@ -1823,12 +1860,15 @@ class PromptGallery { } showToast(severity, summary, detail) { - app.extensionManager.toast.add({ - severity: severity, - summary: summary, - detail: detail, - life: 5000 - }); + const toastsEnabled = document.getElementById("enable-toasts").checked; + + if (toastsEnabled) + app.extensionManager.toast.add({ + severity: severity, + summary: summary, + detail: detail, + life: 5000 + }); } }