"use strict"; // Selects a model by pressing on card function select_model(model_name, event, bool = false, content_type = null, modelPath = null) { if (event) { var className = event.target.className; if (className.includes('custom-checkbox') || className.includes('model-checkbox')) { return; } } if (!modelPath) { modelPath = "Not Found"; } const pathInput = gradioApp().querySelector('#model_path_input textarea'); pathInput.value = modelPath; updateInput(pathInput); const output = bool ? gradioApp().querySelector('#model_sent textarea') : gradioApp().querySelector('#model_select textarea'); if (output && model_name) { const randomNumber = Math.floor(Math.random() * 1000); const paddedNumber = String(randomNumber).padStart(3, '0'); output.value = model_name + "." + paddedNumber; updateInput(output); } if (content_type) { const outputType = gradioApp().querySelector('#type_sent textarea'); const randomNumber = Math.floor(Math.random() * 1000); const paddedNumber = String(randomNumber).padStart(3, '0'); outputType.value = content_type + "." + paddedNumber; updateInput(outputType); } } // Changes the card size function updateCardSize(width, height) { var styleSheet = document.styleSheets[0]; var dimensionsKeyframes = `width: ${width}em !important; height: ${height}em !important;`; var fontSize = (width / 8) * 100; var textKeyframes = `font-size: ${fontSize}% !important;`; addOrUpdateRule(styleSheet, '.civmodelcard img', dimensionsKeyframes); addOrUpdateRule(styleSheet, '.civmodelcard .video-bg', dimensionsKeyframes); addOrUpdateRule(styleSheet, '.civmodelcard figcaption', textKeyframes); } // Toggles NSFW display function toggleNSFWContent(hideAndBlur) { const sheet = document.styleSheets[0]; const toggleRule = (selector, rules) => addOrUpdateRule(sheet, selector, rules); toggleRule('.civcardnsfw', hideAndBlur ? 'display: block;' : 'display: none;'); toggleRule('.civnsfw img', hideAndBlur ? 'filter: none;' : 'filter: blur(10px);'); const dateSections = document.querySelectorAll('.date-section'); dateSections.forEach((section) => { const cards = section.querySelectorAll('.civmodelcard'); const nsfwCards = section.querySelectorAll('.civmodelcard.civcardnsfw'); section.style.display = !hideAndBlur && cards.length === nsfwCards.length ? 'none' : 'block'; }); } // Updates site with css insertions function addOrUpdateRule(styleSheet, selector, newRules) { for (let i = 0; i < styleSheet.cssRules.length; i++) { let rule = styleSheet.cssRules[i]; if (rule.selectorText === selector) { rule.style.cssText = newRules; return; } } styleSheet.insertRule(`${selector} { ${newRules} }`, styleSheet.cssRules.length); } // Updates card border function updateCard(modelNameWithSuffix) { const lastDotIndex = modelNameWithSuffix.lastIndexOf('.'); const modelName = modelNameWithSuffix.slice(0, lastDotIndex); const suffix = modelNameWithSuffix.slice(lastDotIndex + 1); let additionalClassName = ''; switch(suffix) { case 'None': additionalClassName = ''; break; case 'Old': additionalClassName = 'civmodelcardoutdated'; break; case 'New': additionalClassName = 'civmodelcardinstalled'; break; default: return; } const parentDiv = document.querySelector('.civmodellist'); if (parentDiv) { const cards = parentDiv.querySelectorAll('.civmodelcard'); cards.forEach((card) => { const onclickAttr = card.getAttribute('onclick'); if (onclickAttr && onclickAttr.includes(`select_model('${modelName}', event)`)) { card.className = `civmodelcard ${additionalClassName}`; } }); } } // Enables refresh with alt+enter and ctrl+enter document.addEventListener('keydown', function(e) { var handled = false; if (e.key !== undefined) { if ((e.key == "Enter" && (e.metaKey || e.ctrlKey || e.altKey))) handled = true; } else if (e.keyCode !== undefined) { if ((e.keyCode == 13 && (e.metaKey || e.ctrlKey || e.altKey))) handled = true; } if (handled) { var currentTabContent = get_uiCurrentTabContent(); if (currentTabContent && currentTabContent.id === "tab_civitai_interface") { var refreshButton = currentTabContent.querySelector('#refreshBtn'); if (!refreshButton) { refreshButton = currentTabContent.querySelector('#refreshBtnL'); } if (refreshButton) { refreshButton.click(); } e.preventDefault(); } } }); // Function for the back to top button function BackToTop() { const c = Math.max(document.body.scrollTop, document.documentElement.scrollTop); if (c > 0) { window.requestAnimationFrame(BackToTop); document.body.scrollTop = c - c / 8; document.documentElement.scrollTop = c - c / 8; } } // Function to adjust alignment of Filter Accordion function adjustFilterBoxAndButtons() { const element = document.querySelector("#filterBox") || document.querySelector("#filterBoxL"); if (!element) return; const childDiv = element.querySelector("div:nth-child(3)"); if (!childDiv) return; const isLargeScreen = window.innerWidth >= 1250; const isMediumScreen = window.innerWidth < 1250 && window.innerWidth > 915; const isNarrowScreen = window.innerWidth < 800; const modelBlocks = document.querySelectorAll("#civitai_preview_html .model-block"); const civitInfo = document.querySelector(".civitai-version-info"); if (modelBlocks) { modelBlocks.forEach(modelBlock => { if (isNarrowScreen) { modelBlock.style.flexWrap = "wrap"; modelBlock.style.justifyContent = "center"; } else { modelBlock.style.flexWrap = "nowrap"; modelBlock.style.justifyContent = "flex-start"; } }); } if (civitInfo) { if (window.innerWidth < 900) { civitInfo.style.flexWrap = "wrap"; } else { civitInfo.style.flexWrap = "nowrap"; } } childDiv.style.marginLeft = isLargeScreen ? "0px" : isMediumScreen ? `${1250 - window.innerWidth}px` : "0px"; element.style.justifyContent = isLargeScreen || isMediumScreen ? "center" : "flex-start"; const pageBtn1 = document.querySelector("#pageBtn1"); const pageBtn2 = document.querySelector("#pageBtn2"); const pageBox = document.querySelector("#pageBox"); const pageBoxMobile = document.querySelector("#pageBoxMobile"); if (window.innerWidth < 530) { childDiv.style.width = "300px"; if (pageBoxMobile) { pageBtn1 && pageBoxMobile.appendChild(pageBtn1); pageBtn2 && pageBoxMobile.appendChild(pageBtn2); pageBoxMobile.style.paddingBottom = "15px"; } } else { childDiv.style.width = "400px"; if (pageBox) { pageBtn1 && pageBox.insertBefore(pageBtn1, pageBox.firstChild); pageBtn2 && pageBox.appendChild(pageBtn2); pageBoxMobile.style.paddingBottom = "0px"; } } } // Calls the function above whenever the window is resized window.addEventListener("resize", adjustFilterBoxAndButtons); // Function to trigger refresh button with extra checks for page slider function pressRefresh() { setTimeout(() => { const input = document.querySelector("#pageSlider > div:nth-child(2) > div > input"); if (document.activeElement === input) { input.addEventListener('keydown', function(event) { if (event.key === 'Enter' || event.keyCode === 13) { input.blur(); } }); input.addEventListener('blur', function() { return; }); return; } let button = document.querySelector("#refreshBtn"); if (!button) { button = document.querySelector("#refreshBtnL"); } if (button) { button.click(); } else { console.error("Both buttons with IDs #refreshBtn and #refreshBtnL not found."); } }, 200); } // Update SVG Icons based on dark theme or light theme function updateSVGIcons() { const isDark = document.body.classList.contains('dark'); const filterIconUrl = isDark ? "https://gistcdn.githack.com/BlafKing/a20124cedafad23d4eecc1367ec22896/raw/04a4dae0771353377747dadf57c91d55bf841bed/filter-light.svg" : "https://gistcdn.githack.com/BlafKing/686c3438f5d0d13e7e47135f25445ef3/raw/46477777faac7209d001829a171462d9a2ff1467/filter-dark.svg"; const searchIconUrl = isDark ? "https://gistcdn.githack.com/BlafKing/3f95619089bac3b4fd5470a986e1b3bb/raw/ebaa9cceee3436711eb560a7a65e151f1d651c6a/search-light.svg" : "https://gistcdn.githack.com/BlafKing/57573592d5857e102a4bfde852f62639/raw/aa213e9e82d705651603507e26545eb0ffe60c90/search-dark.svg"; const element = document.querySelector("#filterBox, #filterBoxL"); const childDiv = element?.querySelector("div:nth-child(3)"); if (childDiv) { childDiv.style.cssText = `box-shadow: ${isDark ? '#ffffff' : '#000000'} 0px 0px 2px 0px; display: none;`; } const style = document.createElement('style'); style.innerHTML = ` #filterBox > div:nth-child(2) > span:nth-child(2)::before, #filterBoxL > div:nth-child(2) > span:nth-child(2)::before { background: url('${filterIconUrl}') no-repeat center center; background-size: contain; } `; document.head.appendChild(style); const refreshBtn = document.querySelector("#refreshBtn, #refreshBtnL"); const targetSearchElement = refreshBtn?.firstChild || refreshBtnL?.firstChild; if (targetSearchElement) { targetSearchElement.src = searchIconUrl; } } // Creates a tooltip if the user wants to filter liked models without a personal API key function createTooltip(element, hover_element, insertText) { if (element) { const tooltip = document.createElement('div'); tooltip.className = 'browser_tooltip'; tooltip.textContent = insertText; tooltip.style.cssText = 'display: none; text-align: center; white-space: pre;'; hover_element.addEventListener('mouseover', () => { tooltip.style.display = 'block'; }); hover_element.addEventListener('mouseout', () => { tooltip.style.display = 'none'; }); element.appendChild(tooltip); } } // Function that closes filter dropdown if clicked outside the dropdown function setupClickOutsideListener() { var filterBox = document.getElementById("filterBoxL") || document.getElementById("filterBox"); var filterButton = filterBox.getElementsByTagName("div")[1]; var dropDown = filterBox.getElementsByTagName("div")[2]; function clickOutsideHandler(event) { var target = event.target; if (!filterBox.contains(target)) { if (!dropDown.contains(target)) { if (filterButton.className.endsWith("open")) { filterButton.click(); } } } } document.addEventListener("click", clickOutsideHandler); } // Create hyperlink in settings to CivitAI account settings function createLink(infoElement) { const existingText = "(You can create your own API key in your CivitAI account settings, this required for some downloads, Requires UI reload)"; const linkText = "CivitAI account settings"; const [textBefore, textAfter] = existingText.split(linkText); const link = document.createElement('a'); link.textContent = linkText; link.href = 'https://civitai.com/user/account'; link.target = '_blank'; while (infoElement.firstChild) infoElement.removeChild(infoElement.firstChild); infoElement.appendChild(document.createTextNode(textBefore)); infoElement.appendChild(link); infoElement.appendChild(document.createTextNode(textAfter)); } // Function to update the visibility of backToTopDiv based on the intersection with civitaiDiv function updateBackToTopVisibility(entries) { var backToTopDiv = document.getElementById('backToTopContainer'); var civitaiDiv = document.getElementById('civitai_preview_html'); if (civitaiDiv.clientHeight > 0 && entries[0].isIntersecting && window.scrollY !== 0) { backToTopDiv.style.visibility = 'visible'; } else { backToTopDiv.style.visibility = 'hidden'; } } // Options for the Intersection Observer var options = { root: null, rootMargin: '0px 0px -60px 0px', threshold: 0 }; // Create an Intersection Observer instance const observer = new IntersectionObserver(updateBackToTopVisibility, options); function handleCivitaiDivChanges() { var civitaiDiv = document.getElementById('civitai_preview_html'); observer.unobserve(civitaiDiv); observer.observe(civitaiDiv); } document.addEventListener("scroll", handleCivitaiDivChanges) // Create the accordion dropdown inside the settings tab function createAccordion(containerDiv, subfolders, name) { if (containerDiv == null || subfolders.length == 0) { return; } var accordionContainer = document.createElement('div'); accordionContainer.id = 'settings-accordion'; var toggleButton = document.createElement('button'); toggleButton.id = 'accordionToggle'; toggleButton.innerHTML = name + '
'; toggleButton.onclick = function () { accordionDiv.style.display = (accordionDiv.style.display === 'none') ? 'block' : 'none'; toggleButton.lastChild.style.transform = accordionDiv.style.display === 'none' ? 'rotate(90deg)' : 'rotate(0)'; }; accordionContainer.appendChild(toggleButton); var accordionDiv = document.createElement('div'); accordionDiv.classList.add('accordion'); accordionDiv.append(...subfolders); accordionDiv.style.display = 'none'; accordionContainer.appendChild(accordionDiv); containerDiv.appendChild(accordionContainer); } // Adds a button to the cards in txt2img and img2img function createCardButtons(event) { const clickedElement = event.target; const validButtonNames = ['Textual Inversion', 'Hypernetworks', 'Checkpoints', 'Lora']; const validParentIds = ['txt2img_textual_inversion_cards_html', 'txt2img_hypernetworks_cards_html', 'txt2img_checkpoints_cards_html', 'txt2img_lora_cards_html']; const hasMatchingButtonName = clickedElement && clickedElement.innerText && validButtonNames.some(buttonName => clickedElement.innerText.trim() === buttonName ); const flexboxDivs = document.querySelectorAll('.layoutkit-flexbox'); let isLobeTheme = false; flexboxDivs.forEach(div => { const anchorElements = div.querySelectorAll('a'); const hasGitHubLink = Array.from(anchorElements).some(anchor => anchor.href === 'https://github.com/lobehub/sd-webui-lobe-theme/releases'); if (hasGitHubLink) { isLobeTheme = true; } }); if (hasMatchingButtonName || isLobeTheme) { const checkForCardDivs = setInterval(() => { const cardDivs = document.querySelectorAll('.card'); if (cardDivs.length > 0) { clearInterval(checkForCardDivs); const cardScale = document.querySelector('#setting_extra_networks_card_text_scale > div > div > input').valueAsNumber * 100; const viewBoxHeight = (cardScale < 100) ? (100 - cardScale) * 2 : -(cardScale - 100) * 2; cardDivs.forEach(cardDiv => { const buttonRow = cardDiv.querySelector('.button-row'); const actions = cardDiv.querySelector('.actions'); if (!actions) { return; } const nameSpan = actions.querySelector('.name'); let modelName = nameSpan.textContent.trim(); let currentElement = cardDiv.parentElement; let content_type = null; while (currentElement) { const parentId = currentElement.id; if (validParentIds.includes(parentId)) { content_type = parentId; break; } currentElement = currentElement.parentElement; } const existingDiv = buttonRow.querySelector('.goto-civitbrowser.card-button'); if (existingDiv) { return; } const metaDataButton = buttonRow.querySelector('.metadata-button.card-button'); const copyPathButton = buttonRow.querySelector('.copy-path-button.card-button'); let modelPath = ""; if (copyPathButton) { modelPath = copyPathButton.getAttribute('data-clipboard-text'); } const newDiv = document.createElement('div'); newDiv.classList.add('goto-civitbrowser', 'card-button'); newDiv.addEventListener('click', function (event) { event.stopPropagation(); modelInfoPopUp(modelName, content_type, modelPath); }); const svgIcon = document.createElementNS("http://www.w3.org/2000/svg", "svg"); if (isLobeTheme) { svgIcon.setAttribute('width', '25'); svgIcon.setAttribute('height', '25'); } else { if (metaDataButton) { metaDataButton.style.paddingTop = '5px'; metaDataButton.style.width = '42px'; metaDataButton.style.fontSize = '230%'; } svgIcon.setAttribute('width', '40'); svgIcon.setAttribute('height', '40'); newDiv.setAttribute('style', 'width: 42px !important;'); } svgIcon.setAttribute('viewBox', `75 ${viewBoxHeight} 500 500`); svgIcon.setAttribute('fill', 'white'); svgIcon.setAttribute('style', `scale: ${cardScale}%;`); svgIcon.innerHTML = ` `; newDiv.appendChild(svgIcon); buttonRow.insertBefore(newDiv, buttonRow.firstChild); }); } }, 100); } } document.addEventListener('click', createCardButtons); function modelInfoPopUp(modelName, content_type, modelPath) { select_model(modelName, null, true, content_type, modelPath); // Create the overlay var overlay = document.createElement('div'); overlay.classList.add('civitai-overlay'); overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'rgba(20, 20, 20, 0.95)'; overlay.style.zIndex = '1001'; overlay.style.overflowY = 'auto'; // Create the close button var closeButton = document.createElement('div'); closeButton.classList.add('civitai-overlay-close'); closeButton.textContent = '×'; closeButton.style.zIndex = '1011'; closeButton.style.position = 'fixed'; closeButton.style.right = '22px'; closeButton.style.top = '0'; closeButton.style.cursor = 'pointer'; closeButton.style.color = 'white'; closeButton.style.fontSize = '32pt'; closeButton.addEventListener('click', hidePopup); document.addEventListener('keydown', handleKeyPress); // Create the pop-up window var inner = document.createElement('div'); inner.classList.add('civitai-overlay-inner'); inner.style.position = 'absolute'; inner.style.top = '50%'; inner.style.left = '50%'; inner.style.width = 'auto'; inner.style.transform = 'translate(-50%, -50%)'; inner.style.background = 'var(--body-background-fill)'; inner.style.padding = '2em'; inner.style.borderRadius = 'var(--block-radius)'; inner.style.borderStyle = 'solid'; inner.style.borderWidth = 'var(--block-border-width)'; inner.style.borderColor = 'var(--block-border-color)'; inner.style.zIndex = '1001'; // Placeholder model content until model is loaded by other function var modelInfo = document.createElement('div'); modelInfo.classList.add('civitai-overlay-text'); modelInfo.textContent = 'Loading model info, please wait!'; modelInfo.style.fontSize = '24px'; modelInfo.style.color = 'white'; modelInfo.style.fontFamily = 'var(--font)'; document.body.style.overflow = 'hidden'; document.body.appendChild(overlay); overlay.appendChild(closeButton); overlay.appendChild(inner); inner.appendChild(modelInfo); overlay.addEventListener('click', function (event) { if (event.target === overlay) { hidePopup(); } }); setDynamicWidth(inner); // Update width on window resize window.addEventListener('resize', function() { setDynamicWidth(inner); }); } function setDynamicWidth(inner) { var windowWidth = window.innerWidth; var dynamicWidth = Math.min(Math.max(windowWidth - 150, 350), 900); inner.style.width = dynamicWidth + 'px'; } // Function to hide the popup function hidePopup() { var overlay = document.querySelector('.civitai-overlay'); if (overlay) { document.body.removeChild(overlay); document.body.style.overflow = 'auto'; window.removeEventListener('resize', setDynamicWidth); } } // Function to handle key presses function handleKeyPress(event) { if (event.key === 'Escape') { hidePopup(); } } function inputHTMLPreviewContent(html_input) { var inner = document.querySelector('.civitai-overlay-inner') let startIndex = html_input.indexOf("'value': '"); if (startIndex !== -1) { startIndex += "'value': '".length; const endIndex = html_input.indexOf("', 'type': None,", startIndex); if (endIndex !== -1) { let extractedText = html_input.substring(startIndex, endIndex); var modelIdNotFound = extractedText.includes(">Model ID not found.
The"); extractedText = extractedText.replace(/\\n\s* 0) { return; } const genButton = gradioApp().querySelector('#txt2img_extra_tabs > div > button') let input = element.querySelector('dd').textContent; let inf; if (input.endsWith(',')) { inf = input + ' '; } else { inf = input + ', '; } let is_positive = false let is_negative = false switch(type) { case 'prompt': is_positive = true break; case 'negativePrompt': inf = 'Negative prompt: ' + inf; is_negative = true break; case 'seed': inf = 'Seed: ' + inf; inf = inf + inf + inf; break; case 'Size': inf = 'Size: ' + inf; inf = inf + inf + inf; break; case 'Model': inf = 'Model: ' + inf; inf = inf + inf + inf; break; case 'clipSkip': inf = 'Clip skip: ' + inf; inf = inf + inf + inf; break; case 'sampler': inf = 'Sampler: ' + inf; inf = inf + inf + inf; break; case 'steps': inf = 'Steps: ' + inf; inf = inf + inf + inf; break; case 'cfgScale': inf = 'CFG scale: ' + inf; inf = inf + inf + inf; break; } const prompt = gradioApp().querySelector('#txt2img_prompt textarea'); const neg_prompt = gradioApp().querySelector('#txt2img_neg_prompt textarea'); const cfg_scale = gradioApp().querySelector('#txt2img_cfg_scale > div:nth-child(2) > div > input'); let final = ''; let cfg = 'CFG scale: ' + cfg_scale.value + ", " let prompt_addon = cfg + cfg + cfg if (is_positive) { final = inf + "\nNegative prompt: " + neg_prompt.value + "\n" + prompt_addon; } else if (is_negative) { final = prompt.value + "\n" + inf + "\n" + prompt_addon; } else { final = prompt.value + "\nNegative prompt: " + neg_prompt.value + "\n" + inf; } genInfo_to_txt2img(final, false) hidePopup(); sendClick(genButton); } // Creates a list of the selected models var selectedModels = []; var selectedTypes = []; function multi_model_select(modelName, modelType, isChecked) { if (arguments.length === 0) { selectedModels = []; selectedTypes = []; return; } if (isChecked) { if (!selectedModels.includes(modelName)) { selectedModels.push(modelName); } selectedTypes.push(modelType) } else { var modelIndex = selectedModels.indexOf(modelName); if (modelIndex > -1) { selectedModels.splice(modelIndex, 1); } var typesIndex = selectedTypes.indexOf(modelType); if (typesIndex > -1) { selectedTypes.splice(typesIndex, 1); } } const selected_model_list = gradioApp().querySelector('#selected_model_list textarea'); selected_model_list.value = JSON.stringify(selectedModels); const selected_type_list = gradioApp().querySelector('#selected_type_list textarea'); selected_type_list.value = JSON.stringify(selectedTypes); updateInput(selected_model_list); updateInput(selected_type_list); } // Metadata button click detector document.addEventListener('click', function(event) { var target = event.target; if (target.classList.contains('edit-button') && target.classList.contains('card-button')) { var parentDiv = target.parentElement; var actionsDiv = parentDiv.nextElementSibling; if (actionsDiv && actionsDiv.classList.contains('actions')) { var nameSpan = actionsDiv.querySelector('.name'); if (nameSpan) { var nameValue = nameSpan.textContent; onEditButtonCardClick(nameValue); } } } }, true); // CivitAI Link Button Creation function onEditButtonCardClick(nameValue) { var checkInterval = setInterval(function() { var globalPopupInner = document.querySelector('.global-popup-inner'); var titleElement = globalPopupInner.querySelector('.extra-network-name'); if (titleElement.textContent.trim() === nameValue.trim()) { var descriptionSpan = Array.from(globalPopupInner.querySelectorAll('span')).find(span => span.textContent.trim() === "Description"); if (descriptionSpan) { var descriptionTextarea = descriptionSpan.nextElementSibling; if (descriptionTextarea.value.startsWith('Model URL:')) { var matches = descriptionTextarea.value.match(/"([^"]+)"/); if (matches && matches[1]) { var modelUrl = matches[1]; var grandParentDiv = descriptionTextarea.parentElement.parentElement.parentElement.parentElement; var imageDiv = grandParentDiv.nextElementSibling var openInCivitaiDiv = document.querySelector('.open-in-civitai'); if (!openInCivitaiDiv) { openInCivitaiDiv = document.createElement('div'); openInCivitaiDiv.classList.add('open-in-civitai'); imageDiv.appendChild(openInCivitaiDiv); } openInCivitaiDiv.innerHTML = 'Open on CivitAI'; } else { var openInCivitaiDiv = document.querySelector('.open-in-civitai'); if (openInCivitaiDiv) { openInCivitaiDiv.remove(); } } } else { var openInCivitaiDiv = document.querySelector('.open-in-civitai'); if (openInCivitaiDiv) { openInCivitaiDiv.remove(); } } } clearInterval(checkInterval); } }, 100); } function sendClick(location) { const clickEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); location.dispatchEvent(clickEvent); } let currentDlCancelled = false; function cancelCurrentDl() { currentDlCancelled = true; } let allDlCancelled = false; function cancelAllDl() { allDlCancelled = true; } function setSortable() { new Sortable(document.getElementById('queue_list'), { onEnd: function(evt) { const gradio_input = document.querySelector('#civitai_dl_list.prose').innerHTML; const gradio_html = gradioApp().querySelector('#queue_html_input textarea'); let output = gradioApp().querySelector('#arrange_dl_id textarea'); output.value = evt.item.getAttribute('dl_id') + "." + evt.newIndex; updateInput(output); gradio_html.value = gradio_input; updateInput(gradio_html); } }); } function cancelQueueDl() { const cancelBtn = gradioApp().querySelector('#html_cancel_input textarea'); const randomNumber = Math.floor(Math.random() * 1000); const paddedNumber = String(randomNumber).padStart(3, '0'); cancelBtn.value = paddedNumber; updateInput(cancelBtn);cancelBtn } function setDownloadProgressBar() { const gradio_html = gradioApp().querySelector('#queue_html_input textarea'); let browserContainer = document.querySelector('#DownloadProgress'); let browserProgress = browserContainer.querySelector('.progress-bar'); if (!browserProgress || !browserProgress.style.width) { setTimeout(setDownloadProgressBar, 500); return; } let dlList = document.getElementById('civitai_dl_list'); let nonQueue = dlList.querySelector('.civitai_nonqueue_list'); let dlItem = dlList.querySelector('.civitai_dl_item'); let dlBtn = dlItem.querySelector('.dl_action_btn > span'); dlBtn.innerText = "Cancel"; dlBtn.setAttribute('onclick', 'cancelQueueDl()'); let dlId = dlItem.getAttribute('dl_id'); let selector = '.civitai_dl_item[dl_id="' + parseInt(dlId) + '"]'; let dlProgressBar = null; let percentage = null; let dlText = null; nonQueue.appendChild(dlItem); const interval = setInterval(() => { browserContainer = document.querySelector('#DownloadProgress'); browserProgress = browserContainer.querySelector('.progress-bar'); dlText = browserContainer.querySelector('.progress-level-inner'); if (!dlText) { return; } dlText = dlText.innerText percentage = parseFloat(browserProgress.style.width); dlItem = dlList.querySelector(selector); dlProgressBar = dlItem.querySelector('.dl_progress_bar'); dlProgressBar.textContent = percentage.toFixed(1) + '%'; dlProgressBar.style.width = percentage + '%'; if (percentage >= 100) { clearInterval(interval); dlBtn = dlItem.querySelector('.dl_action_btn > span'); dlBtn.innerText = "Remove"; dlBtn.setAttribute('onclick', 'removeDlItem(' + parseInt(dlId) + ', this)'); dlItem.className = 'civitai_dl_item_completed'; dlProgressBar.textContent = 'Completed'; dlProgressBar.style.width = '100%'; const gradio_input = document.querySelector('#civitai_dl_list.prose').innerHTML; gradio_html.value = gradio_input updateInput(gradio_html); return; } if (currentDlCancelled) { clearInterval(interval); dlBtn = dlItem.querySelector('.dl_action_btn > span'); dlBtn.innerText = "Remove"; dlBtn.setAttribute('onclick', 'removeDlItem(' + parseInt(dlId) + ', this)'); currentDlCancelled = false; dlItem.className = 'civitai_dl_item_failed'; dlProgressBar.textContent = 'Cancelled'; dlProgressBar.style.width = "0%"; const gradio_input = document.querySelector('#civitai_dl_list.prose').innerHTML; gradio_html.value = gradio_input updateInput(gradio_html); return; } else if (allDlCancelled) { clearInterval(interval); allDlCancelled = false; let dlItems = dlList.querySelectorAll('.civitai_dl_item'); dlItems.forEach(function(item) { dlBtn = dlItem.querySelector('.dl_action_btn > span'); dlBtn.innerText = "Remove"; dlBtn.setAttribute('onclick', 'removeDlItem(' + parseInt(dlId) + ', this)'); dlProgressBar = item.querySelector('.dl_progress_bar'); dlProgressBar.textContent = 'Cancelled'; dlProgressBar.style.width = "0%"; nonQueue.appendChild(item); item.className = 'civitai_dl_item_failed'; }); const gradio_input = document.querySelector('#civitai_dl_list.prose').innerHTML; gradio_html.value = gradio_input updateInput(gradio_html); return; } else if (dlText.includes('Encountered an error during download of') || dlText.includes('not found on CivitAI servers') || dlText.includes('requires a personal CivitAI API to be downloaded')) { clearInterval(interval); dlBtn = dlItem.querySelector('.dl_action_btn > span'); dlBtn.innerText = "Remove"; dlBtn.setAttribute('onclick', 'removeDlItem(' + parseInt(dlId) + ', this)'); dlItem.className = 'civitai_dl_item_failed'; dlProgressBar.textContent = 'Failed'; dlProgressBar.style.width = "0%"; const gradio_input = document.querySelector('#civitai_dl_list.prose').innerHTML; gradio_html.value = gradio_input updateInput(gradio_html); return; } }, 500); } function removeDlItem(dl_id, element) { const gradio_html = gradioApp().querySelector('#queue_html_input textarea'); const output = gradioApp().querySelector('#remove_dl_id textarea'); var dl_item = element.parentNode.parentNode; dl_item.parentNode.removeChild(dl_item); output.value = dl_id updateInput(output); const gradio_input = document.querySelector('#civitai_dl_list.prose').innerHTML; gradio_html.value = gradio_input; updateInput(gradio_html); } // Selects all models function selectAllModels() { const checkboxes = Array.from(document.querySelectorAll('.model-checkbox')); const allChecked = checkboxes.every(checkbox => checkbox.checked); const allUnchecked = checkboxes.every(checkbox => !checkbox.checked); if (allChecked || allUnchecked) { checkboxes.forEach(sendClick); } else { checkboxes.filter(checkbox => !checkbox.checked).forEach(sendClick); } } // Deselects all models function deselectAllModels() { setTimeout(() => { const checkboxes = Array.from(document.querySelectorAll('.model-checkbox')); checkboxes.filter(checkbox => checkbox.checked).forEach(sendClick); }, 1000); } // Sends Image URL to Python to pull generation info function sendImgUrl(image_url) { const randomNumber = Math.floor(Math.random() * 1000); const genButton = gradioApp().querySelector('#txt2img_extra_tabs > div > button') const paddedNumber = String(randomNumber).padStart(3, '0'); const input = gradioApp().querySelector('#civitai_text2img_input textarea'); input.value = paddedNumber + "." + image_url; updateInput(input); hidePopup(); sendClick(genButton); } // Sends txt2img info to txt2img tab function genInfo_to_txt2img(genInfo, do_slice=true) { let insert = gradioApp().querySelector('#txt2img_prompt textarea'); let pasteButton = gradioApp().querySelector('#paste'); if (genInfo) { insert.value = do_slice ? genInfo.slice(5) : genInfo; insert.dispatchEvent(new Event('input', { bubbles: true })); pasteButton.dispatchEvent(new Event('click', { bubbles: true })); } } // Hide installed models function hideInstalled(toggleValue) { const modelList = document.querySelectorAll('.column.civmodellist > .civmodelcardinstalled') modelList.forEach(item => { item.style.display = toggleValue ? 'none' : 'block'; }); } // Runs all functions when the page is fully loaded function onPageLoad() { const divElement = document.getElementById('setting_custom_api_key'); let civitaiDiv = document.getElementById('civitai_preview_html'); let queue_list = document.querySelector("#queue_list"); const infoElement = divElement?.querySelector('.info'); if (!infoElement) { return; } clearInterval(intervalID); updateSVGIcons(); let subfolderDiv = document.querySelector("#settings_civitai_browser_plus > div > div"); let downloadDiv = document.querySelector("#settings_civitai_browser_download > div > div"); if (subfolderDiv || downloadDiv) { let div = subfolderDiv || downloadDiv; let subfolders = div.querySelectorAll("[id$='subfolder']"); createAccordion(div, subfolders, "Default sub folders"); } let upscalerDiv = document.querySelector("#settings_civitai_browser_plus > div > div > #settings-accordion > div"); let downloadDivSub = document.querySelector("#settings_civitai_browser_download > div > div > #settings-accordion > div"); if (upscalerDiv || downloadDivSub) { let div = upscalerDiv || downloadDivSub; let upscalers = div.querySelectorAll("[id$='upscale_subfolder']"); createAccordion(div, upscalers, "Upscalers"); } let settingsDiv = document.querySelector("#settings_civitai_browser > div > div"); if (subfolderDiv || settingsDiv) { let div = subfolderDiv || settingsDiv; let subfolders = div.querySelectorAll("[id^='setting_insert_sub']"); createAccordion(div, subfolders, "Insert sub folder options"); } let toggle4L = document.getElementById('toggle4L'); let toggle4 = document.getElementById('toggle4'); if (toggle4L || toggle4) { let like_toggle = toggle4L || toggle4; let insertText = 'Requires an API Key\nConfigurable in CivitAI settings tab'; createTooltip(like_toggle, like_toggle, insertText); } let hash_toggle_hover = document.querySelector('#skip_hash_toggle > label'); let hash_toggle = document.querySelector('#skip_hash_toggle'); if (hash_toggle) { let insertText = 'This option generates unique hashes for models that were not downloaded with this extension.\nA hash is required for any of the options below to work, a model with no hash will be skipped.\nInitial hash generation is a one-time process per file.'; createTooltip(hash_toggle, hash_toggle_hover, insertText); } observer.observe(civitaiDiv); queueObserver.observe(queue_list, queueObserverOptions); adjustFilterBoxAndButtons(); setupClickOutsideListener(); createLink(infoElement); updateBackToTopVisibility([{isIntersecting: false}]); } // Checks every second if the page is fully loaded let intervalID = setInterval(onPageLoad, 1000);