sd-civitai-browser-plus/javascript/civitai-html.js

794 lines
32 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"use strict";
// Selects a model by pressing on card
function select_model(model_name, event, bool = false, content_type = null) {
if (event) {
var className = event.target.className;
if (className.includes('custom-checkbox') || className.includes('model-checkbox')) {
return;
}
}
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:
console.error('Unknown suffix', suffix);
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 + '<div style="transition: transform 0.15s; transform: rotate(90deg)">▼</div>';
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 newDiv = document.createElement('div');
newDiv.classList.add('goto-civitbrowser', 'card-button');
newDiv.addEventListener('click', function (event) {
event.stopPropagation();
modelInfoPopUp(modelName, content_type);
});
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 = `
<path d="M 352.79 218.85 L 319.617 162.309 L 203.704 162.479 L 146.28 259.066 L 203.434 355.786 L 319.373 355.729 L 352.773 299.386 L 411.969 299.471 L 348.861 404.911 L 174.065 404.978 L 87.368 259.217 L 174.013 113.246 L 349.147 113.19 L 411.852 218.782 L 352.79 218.85 Z"/>
<path d="M 304.771 334.364 L 213.9 334.429 L 169.607 259.146 L 214.095 183.864 L 305.132 183.907 L 330.489 227.825 L 311.786 259.115 L 330.315 290.655 Z M 278.045 290.682 L 259.294 259.18 L 278.106 227.488 L 240.603 227.366 L 221.983 259.128 L 240.451 291.026 Z"/>
`;
newDiv.appendChild(svgIcon);
buttonRow.insertBefore(newDiv, buttonRow.firstChild);
});
}
}, 100);
}
}
document.addEventListener('click', createCardButtons);
// Sends the selected model list to a python function
function modelInfoPopUp(modelName, content_type) {
select_model(modelName, null, true, content_type);
// Create the overlay
var overlay = document.createElement('div');
overlay.classList.add('civitaiOverlayGlobal');
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 pop-up window
var popup = document.createElement('div');
popup.classList.add('civitaiOverlay');
popup.style.display = 'flex';
popup.style.justifyContent = 'center';
popup.style.position = 'absolute';
popup.style.top = '50%';
popup.style.left = '50%';
popup.style.width = '56em';
popup.style.transform = 'translate(-50%, -50%)';
popup.style.background = 'var(--body-background-fill)';
popup.style.padding = '2em';
popup.style.borderRadius = 'var(--block-radius)';
popup.style.borderStyle = 'solid';
popup.style.borderWidth = 'var(--block-border-width)';
popup.style.borderColor = 'var(--block-border-color)';
popup.style.zIndex = '1001';
// Add content to the popup
var popupContent = document.createElement('div'); // Change from <p> to <div>
popupContent.classList.add('civitaiLoadingText');
popupContent.textContent = 'Loading model info, please wait!';
popupContent.style.fontSize = '24px';
popupContent.style.color = 'white';
popupContent.style.fontFamily = 'var(--font)';
popup.appendChild(popupContent);
// Create the close button
var closeButton = document.createElement('div');
closeButton.textContent = '×';
closeButton.style.position = 'fixed';
closeButton.style.right = '0.25em';
closeButton.style.top = '0';
closeButton.style.cursor = 'pointer';
closeButton.style.color = 'white';
closeButton.style.fontSize = '32pt';
closeButton.addEventListener('click', hidePopup);
document.addEventListener('keydown', handleKeyPress);
// Append the close button to the overlay
overlay.appendChild(closeButton);
// Append the popup to the overlay
overlay.appendChild(popup);
// Append the overlay to the body
document.body.style.overflow = 'hidden'; // Prevent scrolling on the main page
document.body.appendChild(overlay);
overlay.addEventListener('click', function (event) {
if (event.target === overlay) {
hidePopup();
}
});
}
// Function to hide the popup
function hidePopup() {
var overlay = document.querySelector('.civitaiOverlayGlobal');
if (overlay) {
document.body.removeChild(overlay);
document.body.style.overflow = 'auto';
}
}
// Function to handle key presses
function handleKeyPress(event) {
if (event.key === 'Escape') {
hidePopup();
}
}
// 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);
function inputHTMLPreviewContent(html_input) {
var overlay = document.querySelector('.civitaiOverlay')
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.<br>Maybe");
extractedText = extractedText.replace(/\\n\s*</g, '<');
extractedText = extractedText.replace(/\\n/g, ' ');
extractedText = extractedText.replace(/\\t/g, '');
var loadingText = document.querySelector('.civitaiLoadingText');
var modelInfo = document.createElement('div');
loadingText.parentNode.removeChild(loadingText);
if (!modelIdNotFound) {
overlay.style.top = 0;
overlay.style.transform = 'translate(-50%, 0)';
extractedText = extractedText.replace(/\\'/g, "");
} else {
extractedText = extractedText.replace(/\\'/g, "'");
}
modelInfo.innerHTML = extractedText;
overlay.appendChild(modelInfo);
}
}
}
// 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 = '<a href="' + modelUrl + '" target="_blank" onclick="window.open(this.href, \'_blank\'); return false;">Open on CivitAI</a>';
}
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);
}
// 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) {
let insert = gradioApp().querySelector('#txt2img_prompt textarea');
let pasteButton = gradioApp().querySelector('#paste');
if (genInfo) {
var cleanGenInfo = genInfo.slice(5);
insert.value = cleanGenInfo;
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');
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 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);
adjustFilterBoxAndButtons();
setupClickOutsideListener();
createLink(infoElement);
updateBackToTopVisibility([{isIntersecting: false}]);
}
// Checks every second if the page is fully loaded
let intervalID = setInterval(onPageLoad, 1000);