mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2024-11-24 17:24:29 +01:00
074a14f056
Addresses the issues reported by JeLuf: - - gfpgan: the list with models doesn't appear under the <input> box - merge models: As long as no models are selected, the <input> box is very short. - When searching for models by name, the width of the model list shrinks and is smaller than the <input> element.
674 lines
25 KiB
JavaScript
674 lines
25 KiB
JavaScript
"use strict"
|
|
|
|
let modelsCache
|
|
let modelsOptions
|
|
|
|
/*
|
|
*** SEARCHABLE MODELS ***
|
|
Creates searchable dropdowns for SD, VAE, or HN models.
|
|
Also adds a reload models button (placed next to SD models, reloads everything including VAE and HN models).
|
|
More reload buttons may be added at strategic UI locations as needed.
|
|
Merely calling getModels() makes all the magic happen behind the scene to refresh the dropdowns.
|
|
|
|
HOW TO CREATE A MODEL DROPDOWN:
|
|
1) Create an input element. Make sure to add a data-path property, as this is how model dropdowns are identified in auto-save.js.
|
|
<input id="stable_diffusion_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
|
|
|
2) Just declare one of these for your own dropdown (remember to change the element id, e.g. #stable_diffusion_models to your own input's id).
|
|
let stableDiffusionModelField = new ModelDropdown(document.querySelector('#stable_diffusion_model'), 'stable-diffusion')
|
|
let vaeModelField = new ModelDropdown(document.querySelector('#vae_model'), 'vae', 'None')
|
|
let hypernetworkModelField = new ModelDropdown(document.querySelector('#hypernetwork_model'), 'hypernetwork', 'None')
|
|
|
|
3) Model dropdowns will be refreshed automatically when the reload models button is invoked.
|
|
*/
|
|
class ModelDropdown
|
|
{
|
|
modelFilter //= document.querySelector("#model-filter")
|
|
modelFilterArrow //= document.querySelector("#model-filter-arrow")
|
|
modelList //= document.querySelector("#model-list")
|
|
modelResult //= document.querySelector("#model-result")
|
|
modelNoResult //= document.querySelector("#model-no-result")
|
|
|
|
currentSelection //= { elem: undefined, value: '', path: ''}
|
|
highlightedModelEntry //= undefined
|
|
activeModel //= undefined
|
|
|
|
inputModels //= undefined
|
|
modelKey //= undefined
|
|
flatModelList //= []
|
|
noneEntry //= ''
|
|
modelFilterInitialized //= undefined
|
|
|
|
/* MIMIC A REGULAR INPUT FIELD */
|
|
get parentElement() {
|
|
return this.modelFilter.parentElement
|
|
}
|
|
get parentNode() {
|
|
return this.modelFilter.parentNode
|
|
}
|
|
get value() {
|
|
return this.modelFilter.dataset.path
|
|
}
|
|
set value(path) {
|
|
this.modelFilter.dataset.path = path
|
|
this.selectEntry(path)
|
|
}
|
|
addEventListener(type, listener, options) {
|
|
return this.modelFilter.addEventListener(type, listener, options)
|
|
}
|
|
dispatchEvent(event) {
|
|
return this.modelFilter.dispatchEvent(event)
|
|
}
|
|
appendChild(option) {
|
|
// do nothing
|
|
}
|
|
|
|
// remember 'this' - http://blog.niftysnippets.org/2008/04/you-must-remember-this.html
|
|
bind(f, obj) {
|
|
return function() {
|
|
return f.apply(obj, arguments)
|
|
}
|
|
}
|
|
|
|
/* SEARCHABLE INPUT */
|
|
constructor (input, modelKey, noneEntry = '') {
|
|
this.modelFilter = input
|
|
this.noneEntry = noneEntry
|
|
this.modelKey = modelKey
|
|
|
|
if (modelsOptions !== undefined) { // reuse models from cache (only useful for plugins, which are loaded after models)
|
|
this.inputModels = modelsOptions[this.modelKey]
|
|
this.populateModels()
|
|
}
|
|
document.addEventListener("refreshModels", this.bind(function(e) {
|
|
// reload the models
|
|
this.inputModels = modelsOptions[this.modelKey]
|
|
this.populateModels()
|
|
}, this))
|
|
document.addEventListener("collapsibleClick", this.bind(function(e) {
|
|
// update the input size when the element becomes visible
|
|
this.updateInputSize()
|
|
}, this))
|
|
document.addEventListener("tabClick", this.bind(function(e) {
|
|
// update the input size when the tab changes
|
|
this.updateInputSize()
|
|
}, this))
|
|
}
|
|
|
|
saveCurrentSelection(elem, value, path) {
|
|
this.currentSelection.elem = elem
|
|
this.currentSelection.value = value
|
|
this.currentSelection.path = path
|
|
this.modelFilter.dataset.path = path
|
|
this.modelFilter.value = value
|
|
this.modelFilter.dispatchEvent(new Event('change'))
|
|
}
|
|
|
|
processClick(e) {
|
|
e.preventDefault()
|
|
if (e.srcElement.classList.contains('model-file')) {
|
|
this.saveCurrentSelection(e.srcElement, e.srcElement.innerText, e.srcElement.dataset.path)
|
|
this.hideModelList()
|
|
this.modelFilter.focus()
|
|
this.modelFilter.select()
|
|
}
|
|
}
|
|
|
|
getPreviousVisibleSibling(elem) {
|
|
let prevSibling = elem.previousElementSibling
|
|
while (prevSibling && prevSibling.classList.contains('model-file')) {
|
|
if (prevSibling.style.display == 'list-item') return prevSibling
|
|
prevSibling = prevSibling.previousElementSibling
|
|
}
|
|
if (prevSibling && prevSibling.style.display == 'list-item') return prevSibling
|
|
}
|
|
|
|
getLastVisibleChild(elem) {
|
|
let lastElementChild = elem.lastElementChild
|
|
if (lastElementChild.style.display == 'list-item') return lastElementChild
|
|
return this.getPreviousVisibleSibling(lastElementChild)
|
|
}
|
|
|
|
findPreviousSibling(elem) {
|
|
// is there an immediate sibling?
|
|
let prevSibling = this.getPreviousVisibleSibling(elem)
|
|
if (prevSibling) {
|
|
// if the previous sibling is a model file, just select it
|
|
if (prevSibling.classList.contains('model-file')) return prevSibling
|
|
|
|
// if the previous sibling is a model folder, select the last model file it contains
|
|
if (prevSibling.classList.contains('model-folder')) return prevSibling.firstElementChild.lastElementChild
|
|
}
|
|
|
|
// no sibling model file and no sibling model folder. look for siblings around the parent element.
|
|
prevSibling = this.getPreviousVisibleSibling(elem.parentElement.parentElement)
|
|
if (prevSibling) {
|
|
// if the previous entry is a model file, select it
|
|
if (prevSibling.classList.contains('model-file')) return prevSibling
|
|
|
|
// is there another model folder to jump to before the current one?
|
|
if (prevSibling.classList.contains('model-folder')) return this.getLastVisibleChild(prevSibling.firstElementChild)
|
|
}
|
|
}
|
|
|
|
getNextVisibleSibling(elem) {
|
|
let nextSibling = elem.nextElementSibling
|
|
while (nextSibling && nextSibling.classList.contains('model-file')) {
|
|
if (nextSibling.style.display == 'list-item') return nextSibling
|
|
nextSibling = nextSibling.nextElementSibling
|
|
}
|
|
if (nextSibling && nextSibling.style.display == 'list-item') return nextSibling
|
|
}
|
|
|
|
getFirstVisibleChild(elem) {
|
|
let firstElementChild = elem.firstElementChild
|
|
if (firstElementChild.style.display == 'list-item') return firstElementChild
|
|
return this.getNextVisibleSibling(firstElementChild)
|
|
}
|
|
|
|
findNextSibling(elem) {
|
|
// is there an immediate sibling?
|
|
let nextSibling = this.getNextVisibleSibling(elem)
|
|
if (nextSibling) {
|
|
// if the next sibling is a model file, just select it
|
|
if (nextSibling.classList.contains('model-file')) return nextSibling
|
|
|
|
// if the next sibling is a model folder, select the first model file it contains
|
|
if (nextSibling.classList.contains('model-folder')) return nextSibling.firstElementChild.firstElementChild
|
|
}
|
|
|
|
// no sibling model file and no sibling model folder. look for siblings around the parent element.
|
|
nextSibling = this.getNextVisibleSibling(elem.parentElement.parentElement)
|
|
if (nextSibling) {
|
|
// if the next entry is a model file, select it
|
|
if (nextSibling.classList.contains('model-file')) return nextSibling
|
|
|
|
// is there another model folder to jump to after the current one?
|
|
if (nextSibling.classList.contains('model-folder')) return this.getFirstVisibleChild(nextSibling.firstElementChild)
|
|
}
|
|
}
|
|
|
|
selectModelEntry(elem) {
|
|
if (elem) {
|
|
if (this.highlightedModelEntry !== undefined) {
|
|
this.highlightedModelEntry.classList.remove('selected')
|
|
}
|
|
this.saveCurrentSelection(elem, elem.innerText, elem.dataset.path)
|
|
elem.classList.add('selected')
|
|
elem.scrollIntoView({block: 'nearest'})
|
|
this.highlightedModelEntry = elem
|
|
}
|
|
}
|
|
|
|
selectPreviousFile() {
|
|
const elem = this.findPreviousSibling(this.highlightedModelEntry)
|
|
if (elem) {
|
|
this.selectModelEntry(elem)
|
|
}
|
|
else
|
|
{
|
|
//this.highlightedModelEntry.parentElement.parentElement.scrollIntoView({block: 'nearest'})
|
|
this.highlightedModelEntry.closest('.model-list').scrollTop = 0
|
|
}
|
|
this.modelFilter.select()
|
|
}
|
|
|
|
selectNextFile() {
|
|
this.selectModelEntry(this.findNextSibling(this.highlightedModelEntry))
|
|
this.modelFilter.select()
|
|
}
|
|
|
|
selectFirstFile() {
|
|
this.selectModelEntry(this.modelList.querySelector('.model-file'))
|
|
this.highlightedModelEntry.scrollIntoView({block: 'nearest'})
|
|
this.modelFilter.select()
|
|
}
|
|
|
|
selectLastFile() {
|
|
const elems = this.modelList.querySelectorAll('.model-file:last-child')
|
|
this.selectModelEntry(elems[elems.length -1])
|
|
this.modelFilter.select()
|
|
}
|
|
|
|
resetSelection() {
|
|
this.hideModelList()
|
|
this.showAllEntries()
|
|
this.modelFilter.value = this.currentSelection.value
|
|
this.modelFilter.focus()
|
|
this.modelFilter.select()
|
|
}
|
|
|
|
validEntrySelected() {
|
|
return (this.modelNoResult.style.display === 'none')
|
|
}
|
|
|
|
processKey(e) {
|
|
switch (e.key) {
|
|
case 'Escape':
|
|
e.preventDefault()
|
|
this.resetSelection()
|
|
break
|
|
case 'Enter':
|
|
e.preventDefault()
|
|
if (this.validEntrySelected()) {
|
|
if (this.modelList.style.display != 'block') {
|
|
this.showModelList()
|
|
}
|
|
else
|
|
{
|
|
this.saveCurrentSelection(this.highlightedModelEntry, this.highlightedModelEntry.innerText, this.highlightedModelEntry.dataset.path)
|
|
this.hideModelList()
|
|
this.showAllEntries()
|
|
}
|
|
this.modelFilter.focus()
|
|
}
|
|
else
|
|
{
|
|
this.resetSelection()
|
|
}
|
|
break
|
|
case 'ArrowUp':
|
|
e.preventDefault()
|
|
if (this.validEntrySelected()) {
|
|
this.selectPreviousFile()
|
|
}
|
|
break
|
|
case 'ArrowDown':
|
|
e.preventDefault()
|
|
if (this.validEntrySelected()) {
|
|
this.selectNextFile()
|
|
}
|
|
break
|
|
case 'ArrowLeft':
|
|
if (this.modelList.style.display != 'block') {
|
|
e.preventDefault()
|
|
}
|
|
break
|
|
case 'ArrowRight':
|
|
if (this.modelList.style.display != 'block') {
|
|
e.preventDefault()
|
|
}
|
|
break
|
|
case 'PageUp':
|
|
e.preventDefault()
|
|
if (this.validEntrySelected()) {
|
|
this.selectPreviousFile()
|
|
this.selectPreviousFile()
|
|
this.selectPreviousFile()
|
|
this.selectPreviousFile()
|
|
this.selectPreviousFile()
|
|
this.selectPreviousFile()
|
|
this.selectPreviousFile()
|
|
this.selectPreviousFile()
|
|
}
|
|
break
|
|
case 'PageDown':
|
|
e.preventDefault()
|
|
if (this.validEntrySelected()) {
|
|
this.selectNextFile()
|
|
this.selectNextFile()
|
|
this.selectNextFile()
|
|
this.selectNextFile()
|
|
this.selectNextFile()
|
|
this.selectNextFile()
|
|
this.selectNextFile()
|
|
this.selectNextFile()
|
|
}
|
|
break
|
|
case 'Home':
|
|
//if (this.modelList.style.display != 'block') {
|
|
e.preventDefault()
|
|
if (this.validEntrySelected()) {
|
|
this.selectFirstFile()
|
|
}
|
|
//}
|
|
break
|
|
case 'End':
|
|
//if (this.modelList.style.display != 'block') {
|
|
e.preventDefault()
|
|
if (this.validEntrySelected()) {
|
|
this.selectLastFile()
|
|
}
|
|
//}
|
|
break
|
|
default:
|
|
//console.log(e.key)
|
|
}
|
|
}
|
|
|
|
modelListFocus() {
|
|
this.selectEntry()
|
|
this.showAllEntries()
|
|
}
|
|
|
|
showModelList() {
|
|
this.modelList.style.display = 'block'
|
|
this.selectEntry()
|
|
this.showAllEntries()
|
|
this.modelFilter.value = ''
|
|
this.modelFilter.focus()
|
|
this.modelFilter.style.cursor = 'auto'
|
|
}
|
|
|
|
hideModelList() {
|
|
this.modelList.style.display = 'none'
|
|
this.modelFilter.value = this.currentSelection.value
|
|
this.modelFilter.style.cursor = ''
|
|
}
|
|
|
|
toggleModelList(e) {
|
|
e.preventDefault()
|
|
if (this.modelList.style.display != 'block') {
|
|
this.showModelList()
|
|
}
|
|
else
|
|
{
|
|
this.hideModelList()
|
|
this.modelFilter.select()
|
|
}
|
|
}
|
|
|
|
selectEntry(path) {
|
|
if (path !== undefined) {
|
|
const entries = this.modelList.querySelectorAll('.model-file');
|
|
|
|
for (let i = 0; i < entries.length; i++) {
|
|
if (entries[i].dataset.path == path) {
|
|
this.saveCurrentSelection(entries[i], entries[i].innerText, entries[i].dataset.path)
|
|
this.highlightedModelEntry = entries[i]
|
|
entries[i].scrollIntoView({block: 'nearest'})
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.currentSelection.elem !== undefined) {
|
|
// select the previous element
|
|
if (this.highlightedModelEntry !== undefined && this.highlightedModelEntry != this.currentSelection.elem) {
|
|
this.highlightedModelEntry.classList.remove('selected')
|
|
}
|
|
this.currentSelection.elem.classList.add('selected')
|
|
this.highlightedModelEntry = this.currentSelection.elem
|
|
this.currentSelection.elem.scrollIntoView({block: 'nearest'})
|
|
}
|
|
else
|
|
{
|
|
this.selectFirstFile()
|
|
}
|
|
}
|
|
|
|
highlightModelAtPosition(e) {
|
|
let elem = document.elementFromPoint(e.clientX, e.clientY)
|
|
|
|
if (elem.classList.contains('model-file')) {
|
|
this.highlightModel(elem)
|
|
}
|
|
}
|
|
|
|
highlightModel(elem) {
|
|
if (elem.classList.contains('model-file')) {
|
|
if (this.highlightedModelEntry !== undefined && this.highlightedModelEntry != elem) {
|
|
this.highlightedModelEntry.classList.remove('selected')
|
|
}
|
|
elem.classList.add('selected')
|
|
this.highlightedModelEntry = elem
|
|
}
|
|
}
|
|
|
|
showAllEntries() {
|
|
this.modelList.querySelectorAll('li').forEach(function(li) {
|
|
if (li.id !== 'model-no-result') {
|
|
li.style.display = 'list-item'
|
|
}
|
|
})
|
|
this.modelNoResult.style.display = 'none'
|
|
}
|
|
|
|
filterList(e) {
|
|
const filter = this.modelFilter.value.toLowerCase()
|
|
let found = false
|
|
let showAllChildren = false
|
|
|
|
this.modelList.querySelectorAll('li').forEach(function(li) {
|
|
if (li.classList.contains('model-folder')) {
|
|
showAllChildren = false
|
|
}
|
|
if (filter == '') {
|
|
li.style.display = 'list-item'
|
|
found = true
|
|
} else if (showAllChildren || li.textContent.toLowerCase().match(filter)) {
|
|
li.style.display = 'list-item'
|
|
if (li.classList.contains('model-folder') && li.firstChild.textContent.toLowerCase().match(filter)) {
|
|
showAllChildren = true
|
|
}
|
|
found = true
|
|
} else {
|
|
li.style.display = 'none'
|
|
}
|
|
})
|
|
|
|
if (found) {
|
|
this.modelResult.style.display = 'list-item'
|
|
this.modelNoResult.style.display = 'none'
|
|
const elem = this.findNextSibling(this.modelList.querySelector('.model-file'))
|
|
this.highlightModel(elem)
|
|
elem.scrollIntoView({block: 'nearest'})
|
|
}
|
|
else
|
|
{
|
|
this.modelResult.style.display = 'none'
|
|
this.modelNoResult.style.display = 'list-item'
|
|
}
|
|
this.modelList.style.display = 'block'
|
|
}
|
|
|
|
/* MODEL LOADER */
|
|
getElementDimensions(element) {
|
|
// Clone the element
|
|
const clone = element.cloneNode(true)
|
|
|
|
// Copy the styles of the original element to the cloned element
|
|
const originalStyles = window.getComputedStyle(element)
|
|
for (let i = 0; i < originalStyles.length; i++) {
|
|
const property = originalStyles[i]
|
|
clone.style[property] = originalStyles.getPropertyValue(property)
|
|
}
|
|
|
|
// Set its visibility to hidden and display to inline-block
|
|
clone.style.visibility = "hidden"
|
|
clone.style.display = "inline-block"
|
|
|
|
// Put the cloned element next to the original element
|
|
element.parentNode.insertBefore(clone, element.nextSibling)
|
|
|
|
// Get its width and height
|
|
const width = clone.offsetWidth
|
|
const height = clone.offsetHeight
|
|
|
|
// Remove it from the DOM
|
|
clone.remove()
|
|
|
|
// Return its width and height
|
|
return { width, height }
|
|
}
|
|
|
|
updateInputSize() {
|
|
if (this.modelList !== undefined) {
|
|
const dimensions = this.getElementDimensions(this.modelList)
|
|
this.modelFilter.style.width = dimensions.width + 'px'
|
|
this.modelList.style.width = dimensions.width + 'px'
|
|
this.modelFilterArrow.style.height = dimensions.height + 'px'
|
|
if (this.modelFilter.offsetLeft > 0) {
|
|
this.modelList.style.left = this.modelFilter.offsetLeft + 'px'
|
|
}
|
|
}
|
|
}
|
|
|
|
flattenModelList(models, path) {
|
|
models.forEach(entry => {
|
|
if (Array.isArray(entry)) {
|
|
this.flattenModelList(entry[1], path + '/' + entry[0])
|
|
}
|
|
else
|
|
{
|
|
this.flatModelList.push(path == '' ? entry : path + '/' + entry)
|
|
}
|
|
})
|
|
}
|
|
|
|
// sort models
|
|
getFolder(model) {
|
|
return model.substring(0, model.lastIndexOf('/') + 1)
|
|
}
|
|
|
|
sortModels(models) {
|
|
// sort the models in alphabetical order, root folder models last
|
|
models.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
|
|
/*
|
|
// sort the models in alphabetical order, root folder models first
|
|
models = models.sort()
|
|
let found
|
|
do {
|
|
found = false
|
|
for (let i = 0; i < models.length - 1; i++) {
|
|
if (
|
|
(this.getFolder(models[i]) === this.getFolder(models[i+1]) && models[i].toLowerCase().localeCompare(models[i+1].toLowerCase()) > 0) // same folder, sort by alphabetical order
|
|
|| (this.getFolder(models[i]).toLowerCase().localeCompare(this.getFolder(models[i+1]).toLowerCase()) > 0) // L1 folder > L2 folder
|
|
) {
|
|
[models[i], models[i+1]] = [models[i+1], models[i]]
|
|
found = true
|
|
}
|
|
}
|
|
} while (found)
|
|
*/
|
|
}
|
|
|
|
populateModels() {
|
|
this.activeModel = this.modelFilter.dataset.path
|
|
|
|
this.currentSelection = { elem: undefined, value: '', path: ''}
|
|
this.highlightedModelEntry = undefined
|
|
this.flatModelList = []
|
|
|
|
if(this.modelList !== undefined) {
|
|
this.modelList.remove()
|
|
this.modelFilterArrow.remove()
|
|
}
|
|
this.createDropdown()
|
|
}
|
|
|
|
createDropdown() {
|
|
// prepare to sort the models
|
|
this.flattenModelList(this.inputModels, '')
|
|
this.sortModels(this.flatModelList)
|
|
|
|
// create dropdown entries
|
|
this.modelFilter.insertAdjacentHTML('afterend', this.parseModels(this.flatModelList))
|
|
this.modelFilter.classList.add('model-selector')
|
|
this.modelFilterArrow = document.querySelector(`#${this.modelFilter.id}-model-filter-arrow`)
|
|
this.modelList = document.querySelector(`#${this.modelFilter.id}-model-list`)
|
|
this.modelResult = document.querySelector(`#${this.modelFilter.id}-model-result`)
|
|
this.modelNoResult = document.querySelector(`#${this.modelFilter.id}-model-no-result`)
|
|
this.updateInputSize()
|
|
|
|
if (this.modelFilterInitialized !== true) {
|
|
this.modelFilter.addEventListener('input', this.bind(this.filterList, this))
|
|
this.modelFilter.addEventListener('focus', this.bind(this.modelListFocus, this))
|
|
this.modelFilter.addEventListener('blur', this.bind(this.hideModelList, this))
|
|
this.modelFilter.addEventListener('click', this.bind(this.showModelList, this))
|
|
this.modelFilter.addEventListener('keydown', this.bind(this.processKey, this))
|
|
|
|
this.modelFilterInitialized = true
|
|
}
|
|
this.modelFilterArrow.addEventListener('mousedown', this.bind(this.toggleModelList, this))
|
|
this.modelList.addEventListener('mousemove', this.bind(this.highlightModelAtPosition, this))
|
|
this.modelList.addEventListener('mousedown', this.bind(this.processClick, this))
|
|
|
|
this.selectEntry(this.activeModel)
|
|
}
|
|
|
|
parseModels(models) {
|
|
let html = `<i id="${this.modelFilter.id}-model-filter-arrow" class="model-selector-arrow fa-solid fa-angle-down"></i>
|
|
<ul id="${this.modelFilter.id}-model-list" class="model-list">
|
|
<li id="${this.modelFilter.id}-model-no-result" class="model-no-result">No result</li>
|
|
<li id="${this.modelFilter.id}-model-result" class="model-result">
|
|
<ul>
|
|
`
|
|
if (this.noneEntry != '') {
|
|
html += `<li data-path='' class='model-file in-root-folder'>${this.noneEntry}</li>`
|
|
}
|
|
|
|
let currentFolder = ''
|
|
models.forEach(entry => {
|
|
const folder = entry.substring(0, 1) == '/' ? entry.substring(1, entry.lastIndexOf('/')) : ''
|
|
if (folder !== '' && folder !== currentFolder) {
|
|
if (currentFolder != '') {
|
|
html += '</ul></li>'
|
|
}
|
|
html += `<li class='model-folder'>/${folder}<ul>`
|
|
currentFolder = folder
|
|
}
|
|
else if (folder == '' && currentFolder !== '') {
|
|
currentFolder = ''
|
|
html += '</ul></li>'
|
|
}
|
|
const modelName = entry.substring(entry.lastIndexOf('/') + 1)
|
|
if (entry.substring(0, 1) == '/') {
|
|
entry = entry.substring(1)
|
|
}
|
|
html += `<li data-path='${entry}' class='model-file${currentFolder == '' ? ' in-root-folder' : ''}'>${modelName}</li>`
|
|
})
|
|
if (currentFolder != '') {
|
|
html += '</ul></li>'
|
|
}
|
|
|
|
html += `
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
`
|
|
return html
|
|
}
|
|
}
|
|
|
|
/* (RE)LOAD THE MODELS */
|
|
async function getModels() {
|
|
try {
|
|
modelsCache = await SD.getModels()
|
|
modelsOptions = modelsCache['options']
|
|
if ("scan-error" in modelsCache) {
|
|
// let previewPane = document.getElementById('tab-content-wrapper')
|
|
let previewPane = document.getElementById('preview')
|
|
previewPane.style.background="red"
|
|
previewPane.style.textAlign="center"
|
|
previewPane.innerHTML = '<H1>🔥Malware alert!🔥</H1><h2>The file <i>' + modelsCache['scan-error'] + '</i> in your <tt>models/stable-diffusion</tt> folder is probably malware infected.</h2><h2>Please delete this file from the folder before proceeding!</h2>After deleting the file, reload this page.<br><br><button onClick="window.location.reload();">Reload Page</button>'
|
|
makeImageBtn.disabled = true
|
|
}
|
|
|
|
/* This code should no longer be needed. Commenting out for now, will cleanup later.
|
|
const sd_model_setting_key = "stable_diffusion_model"
|
|
const vae_model_setting_key = "vae_model"
|
|
const hypernetwork_model_key = "hypernetwork_model"
|
|
|
|
const stableDiffusionOptions = modelsOptions['stable-diffusion']
|
|
const vaeOptions = modelsOptions['vae']
|
|
const hypernetworkOptions = modelsOptions['hypernetwork']
|
|
|
|
// TODO: set default for model here too
|
|
SETTINGS[sd_model_setting_key].default = stableDiffusionOptions[0]
|
|
if (getSetting(sd_model_setting_key) == '' || SETTINGS[sd_model_setting_key].value == '') {
|
|
setSetting(sd_model_setting_key, stableDiffusionOptions[0])
|
|
}
|
|
*/
|
|
|
|
// notify ModelDropdown objects to refresh
|
|
document.dispatchEvent(new Event('refreshModels'))
|
|
} catch (e) {
|
|
console.log('get models error', e)
|
|
}
|
|
}
|
|
|
|
// reload models button
|
|
document.querySelector('#reload-models').addEventListener('click', getModels)
|