refactor: Migrate the project functionality and optimize the code structure
This commit is contained in:
39
src/utils/common.ts
Normal file
39
src/utils/common.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export const bytesToSize = (
|
||||
bytes: number | string | undefined | null,
|
||||
decimals = 2,
|
||||
) => {
|
||||
if (typeof bytes === 'undefined' || bytes === null) {
|
||||
bytes = 0
|
||||
}
|
||||
if (typeof bytes === 'string') {
|
||||
bytes = Number(bytes)
|
||||
}
|
||||
if (Number.isNaN(bytes)) {
|
||||
return 'Unknown'
|
||||
}
|
||||
if (bytes === 0) {
|
||||
return '0 Bytes'
|
||||
}
|
||||
const k = 1024
|
||||
const dm = decimals < 0 ? 0 : decimals
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
export const formatDate = (date: number | string | Date) => {
|
||||
return dayjs(date).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
export const previewUrlToFile = async (url: string) => {
|
||||
return fetch(url)
|
||||
.then((res) => res.blob())
|
||||
.then((blob) => {
|
||||
const type = blob.type
|
||||
const extension = type.split('/')[1]
|
||||
const file = new File([blob], `preview.${extension}`, { type })
|
||||
return file
|
||||
})
|
||||
}
|
||||
620
src/utils/legacy.ts
Normal file
620
src/utils/legacy.ts
Normal file
@@ -0,0 +1,620 @@
|
||||
// @ts-nocheck
|
||||
import { app } from 'scripts/comfyAPI'
|
||||
|
||||
const LiteGraph = window.LiteGraph
|
||||
|
||||
const modelNodeType = {
|
||||
checkpoints: 'CheckpointLoaderSimple',
|
||||
clip: 'CLIPLoader',
|
||||
clip_vision: 'CLIPVisionLoader',
|
||||
controlnet: 'ControlNetLoader',
|
||||
diffusers: 'DiffusersLoader',
|
||||
embeddings: 'Embedding',
|
||||
gligen: 'GLIGENLoader',
|
||||
hypernetworks: 'HypernetworkLoader',
|
||||
photomaker: 'PhotoMakerLoader',
|
||||
loras: 'LoraLoader',
|
||||
style_models: 'StyleModelLoader',
|
||||
unet: 'UNETLoader',
|
||||
upscale_models: 'UpscaleModelLoader',
|
||||
vae: 'VAELoader',
|
||||
vae_approx: undefined,
|
||||
}
|
||||
|
||||
export class ModelGrid {
|
||||
/**
|
||||
* @param {string} nodeType
|
||||
* @returns {int}
|
||||
*/
|
||||
static modelWidgetIndex(nodeType) {
|
||||
return nodeType === undefined ? -1 : 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {string} file
|
||||
* @param {boolean} removeExtension
|
||||
* @returns {string}
|
||||
*/
|
||||
static insertEmbeddingIntoText(text, file, removeExtension) {
|
||||
let name = file
|
||||
if (removeExtension) {
|
||||
name = SearchPath.splitExtension(name)[0]
|
||||
}
|
||||
const sep = text.length === 0 || text.slice(-1).match(/\s/) ? '' : ' '
|
||||
return text + sep + '(embedding:' + name + ':1.0)'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} list
|
||||
* @param {string} searchString
|
||||
* @returns {Array}
|
||||
*/
|
||||
static #filter(list, searchString) {
|
||||
/** @type {string[]} */
|
||||
const keywords = searchString
|
||||
//.replace("*", " ") // TODO: this is wrong for wildcards
|
||||
.split(/(-?".*?"|[^\s"]+)+/g)
|
||||
.map((item) =>
|
||||
item
|
||||
.trim()
|
||||
.replace(/(?:")+/g, '')
|
||||
.toLowerCase(),
|
||||
)
|
||||
.filter(Boolean)
|
||||
|
||||
const regexSHA256 = /^[a-f0-9]{64}$/gi
|
||||
const fields = ['name', 'path']
|
||||
return list.filter((element) => {
|
||||
const text = fields
|
||||
.reduce((memo, field) => memo + ' ' + element[field], '')
|
||||
.toLowerCase()
|
||||
return keywords.reduce((memo, target) => {
|
||||
const excludeTarget = target[0] === '-'
|
||||
if (excludeTarget && target.length === 1) {
|
||||
return memo
|
||||
}
|
||||
const filteredTarget = excludeTarget ? target.slice(1) : target
|
||||
if (
|
||||
element['SHA256'] !== undefined &&
|
||||
regexSHA256.test(filteredTarget)
|
||||
) {
|
||||
return (
|
||||
memo && excludeTarget !== (filteredTarget === element['SHA256'])
|
||||
)
|
||||
} else {
|
||||
return memo && excludeTarget !== text.includes(filteredTarget)
|
||||
}
|
||||
}, true)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* In-place sort. Returns an array alias.
|
||||
* @param {Array} list
|
||||
* @param {string} sortBy
|
||||
* @param {bool} [reverse=false]
|
||||
* @returns {Array}
|
||||
*/
|
||||
static #sort(list, sortBy, reverse = false) {
|
||||
let compareFn = null
|
||||
switch (sortBy) {
|
||||
case MODEL_SORT_DATE_NAME:
|
||||
compareFn = (a, b) => {
|
||||
return a[MODEL_SORT_DATE_NAME].localeCompare(b[MODEL_SORT_DATE_NAME])
|
||||
}
|
||||
break
|
||||
case MODEL_SORT_DATE_MODIFIED:
|
||||
compareFn = (a, b) => {
|
||||
return b[MODEL_SORT_DATE_MODIFIED] - a[MODEL_SORT_DATE_MODIFIED]
|
||||
}
|
||||
break
|
||||
case MODEL_SORT_DATE_CREATED:
|
||||
compareFn = (a, b) => {
|
||||
return b[MODEL_SORT_DATE_CREATED] - a[MODEL_SORT_DATE_CREATED]
|
||||
}
|
||||
break
|
||||
case MODEL_SORT_SIZE_BYTES:
|
||||
compareFn = (a, b) => {
|
||||
return b[MODEL_SORT_SIZE_BYTES] - a[MODEL_SORT_SIZE_BYTES]
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.warn("Invalid filter sort value: '" + sortBy + "'")
|
||||
return list
|
||||
}
|
||||
const sorted = list.sort(compareFn)
|
||||
return reverse ? sorted.reverse() : sorted
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} event
|
||||
* @param {string} modelType
|
||||
* @param {string} path
|
||||
* @param {boolean} removeEmbeddingExtension
|
||||
* @param {int} addOffset
|
||||
*/
|
||||
static #addModel(
|
||||
event,
|
||||
modelType,
|
||||
path,
|
||||
removeEmbeddingExtension,
|
||||
addOffset,
|
||||
) {
|
||||
let success = false
|
||||
if (modelType !== 'embeddings') {
|
||||
const nodeType = modelNodeType[modelType]
|
||||
const widgetIndex = ModelGrid.modelWidgetIndex(nodeType)
|
||||
let node = LiteGraph.createNode(nodeType, null, [])
|
||||
if (widgetIndex !== -1 && node) {
|
||||
node.widgets[widgetIndex].value = path
|
||||
const selectedNodes = app.canvas.selected_nodes
|
||||
let isSelectedNode = false
|
||||
for (var i in selectedNodes) {
|
||||
const selectedNode = selectedNodes[i]
|
||||
node.pos[0] = selectedNode.pos[0] + addOffset
|
||||
node.pos[1] = selectedNode.pos[1] + addOffset
|
||||
isSelectedNode = true
|
||||
break
|
||||
}
|
||||
if (!isSelectedNode) {
|
||||
const graphMouse = app.canvas.graph_mouse
|
||||
node.pos[0] = graphMouse[0]
|
||||
node.pos[1] = graphMouse[1]
|
||||
}
|
||||
app.graph.add(node, { doProcessChange: true })
|
||||
app.canvas.selectNode(node)
|
||||
success = true
|
||||
}
|
||||
event.stopPropagation()
|
||||
} else if (modelType === 'embeddings') {
|
||||
const [embeddingDirectory, embeddingFile] = SearchPath.split(path)
|
||||
const selectedNodes = app.canvas.selected_nodes
|
||||
for (var i in selectedNodes) {
|
||||
const selectedNode = selectedNodes[i]
|
||||
const nodeType = modelNodeType[modelType]
|
||||
const widgetIndex = ModelGrid.modelWidgetIndex(nodeType)
|
||||
const target = selectedNode?.widgets[widgetIndex]?.element
|
||||
if (target && target.type === 'textarea') {
|
||||
target.value = ModelGrid.insertEmbeddingIntoText(
|
||||
target.value,
|
||||
embeddingFile,
|
||||
removeEmbeddingExtension,
|
||||
)
|
||||
success = true
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
console.warn('Try selecting a node before adding the embedding.')
|
||||
}
|
||||
event.stopPropagation()
|
||||
}
|
||||
comfyButtonAlert(event.target, success, 'mdi-check-bold', 'mdi-close-thick')
|
||||
}
|
||||
|
||||
static #getWidgetComboIndices(node, value) {
|
||||
const widgetIndices = []
|
||||
node?.widgets?.forEach((widget, index) => {
|
||||
if (widget.type === 'combo' && widget.options.values?.includes(value)) {
|
||||
widgetIndices.push(index)
|
||||
}
|
||||
})
|
||||
return widgetIndices
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DragEvent} event
|
||||
* @param {string} modelType
|
||||
* @param {string} path
|
||||
* @param {boolean} removeEmbeddingExtension
|
||||
* @param {boolean} strictlyOnWidget
|
||||
*/
|
||||
static dragAddModel(
|
||||
event,
|
||||
modelType,
|
||||
path,
|
||||
removeEmbeddingExtension,
|
||||
strictlyOnWidget,
|
||||
) {
|
||||
const target = document.elementFromPoint(event.clientX, event.clientY)
|
||||
if (modelType !== 'embeddings' && target.id === 'graph-canvas') {
|
||||
const pos = app.canvas.convertEventToCanvasOffset(event)
|
||||
|
||||
const node = app.graph.getNodeOnPos(
|
||||
pos[0],
|
||||
pos[1],
|
||||
app.canvas.visible_nodes,
|
||||
)
|
||||
|
||||
let widgetIndex = -1
|
||||
if (widgetIndex === -1) {
|
||||
const widgetIndices = this.#getWidgetComboIndices(node, path)
|
||||
if (widgetIndices.length === 0) {
|
||||
widgetIndex = -1
|
||||
} else if (widgetIndices.length === 1) {
|
||||
widgetIndex = widgetIndices[0]
|
||||
if (strictlyOnWidget) {
|
||||
const draggedWidget = app.canvas.processNodeWidgets(
|
||||
node,
|
||||
pos,
|
||||
event,
|
||||
)
|
||||
const widget = node.widgets[widgetIndex]
|
||||
if (draggedWidget != widget) {
|
||||
// != check NOT same object
|
||||
widgetIndex = -1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// ambiguous widget (strictlyOnWidget always true)
|
||||
const draggedWidget = app.canvas.processNodeWidgets(node, pos, event)
|
||||
widgetIndex = widgetIndices.findIndex((index) => {
|
||||
return draggedWidget == node.widgets[index] // == check same object
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (widgetIndex !== -1) {
|
||||
node.widgets[widgetIndex].value = path
|
||||
app.canvas.selectNode(node)
|
||||
} else {
|
||||
const expectedNodeType = modelNodeType[modelType]
|
||||
const newNode = LiteGraph.createNode(expectedNodeType, null, [])
|
||||
let newWidgetIndex = ModelGrid.modelWidgetIndex(expectedNodeType)
|
||||
if (newWidgetIndex === -1) {
|
||||
newWidgetIndex = this.#getWidgetComboIndices(newNode, path)[0] ?? -1
|
||||
}
|
||||
if (
|
||||
newNode !== undefined &&
|
||||
newNode !== null &&
|
||||
newWidgetIndex !== -1
|
||||
) {
|
||||
newNode.pos[0] = pos[0]
|
||||
newNode.pos[1] = pos[1]
|
||||
newNode.widgets[newWidgetIndex].value = path
|
||||
app.graph.add(newNode, { doProcessChange: true })
|
||||
app.canvas.selectNode(newNode)
|
||||
}
|
||||
}
|
||||
event.stopPropagation()
|
||||
} else if (modelType === 'embeddings' && target.type === 'textarea') {
|
||||
const pos = app.canvas.convertEventToCanvasOffset(event)
|
||||
const nodeAtPos = app.graph.getNodeOnPos(
|
||||
pos[0],
|
||||
pos[1],
|
||||
app.canvas.visible_nodes,
|
||||
)
|
||||
if (nodeAtPos) {
|
||||
app.canvas.selectNode(nodeAtPos)
|
||||
const [embeddingDirectory, embeddingFile] = SearchPath.split(path)
|
||||
target.value = ModelGrid.insertEmbeddingIntoText(
|
||||
target.value,
|
||||
embeddingFile,
|
||||
removeEmbeddingExtension,
|
||||
)
|
||||
event.stopPropagation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} event
|
||||
* @param {string} modelType
|
||||
* @param {string} path
|
||||
* @param {boolean} removeEmbeddingExtension
|
||||
*/
|
||||
static #copyModelToClipboard(
|
||||
event,
|
||||
modelType,
|
||||
path,
|
||||
removeEmbeddingExtension,
|
||||
) {
|
||||
const nodeType = modelNodeType[modelType]
|
||||
let success = false
|
||||
if (nodeType === 'Embedding') {
|
||||
if (navigator.clipboard) {
|
||||
const [embeddingDirectory, embeddingFile] = SearchPath.split(path)
|
||||
const embeddingText = ModelGrid.insertEmbeddingIntoText(
|
||||
'',
|
||||
embeddingFile,
|
||||
removeEmbeddingExtension,
|
||||
)
|
||||
navigator.clipboard.writeText(embeddingText)
|
||||
success = true
|
||||
} else {
|
||||
console.warn(
|
||||
'Cannot copy the embedding to the system clipboard; Try dragging it instead.',
|
||||
)
|
||||
}
|
||||
} else if (nodeType) {
|
||||
const node = LiteGraph.createNode(nodeType, null, [])
|
||||
const widgetIndex = ModelGrid.modelWidgetIndex(nodeType)
|
||||
if (widgetIndex !== -1) {
|
||||
node.widgets[widgetIndex].value = path
|
||||
app.canvas.copyToClipboard([node])
|
||||
success = true
|
||||
}
|
||||
} else {
|
||||
console.warn(`Unable to copy unknown model type '${modelType}.`)
|
||||
}
|
||||
comfyButtonAlert(event.target, success, 'mdi-check-bold', 'mdi-close-thick')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} models
|
||||
* @param {string} modelType
|
||||
* @param {Object.<HTMLInputElement>} settingsElements
|
||||
* @param {String} searchSeparator
|
||||
* @param {String} systemSeparator
|
||||
* @param {(searchPath: string) => Promise<void>} showModelInfo
|
||||
* @returns {HTMLElement[]}
|
||||
*/
|
||||
static #generateInnerHtml(
|
||||
models,
|
||||
modelType,
|
||||
settingsElements,
|
||||
searchSeparator,
|
||||
systemSeparator,
|
||||
showModelInfo,
|
||||
) {
|
||||
// TODO: separate text and model logic; getting too messy
|
||||
// TODO: fallback on button failure to copy text?
|
||||
const canShowButtons = modelNodeType[modelType] !== undefined
|
||||
const showAddButton =
|
||||
canShowButtons && settingsElements['model-show-add-button'].checked
|
||||
const showCopyButton =
|
||||
canShowButtons && settingsElements['model-show-copy-button'].checked
|
||||
const showLoadWorkflowButton =
|
||||
canShowButtons &&
|
||||
settingsElements['model-show-load-workflow-button'].checked
|
||||
const strictDragToAdd =
|
||||
settingsElements['model-add-drag-strict-on-field'].checked
|
||||
const addOffset = parseInt(settingsElements['model-add-offset'].value)
|
||||
const showModelExtension =
|
||||
settingsElements['model-show-label-extensions'].checked
|
||||
const modelInfoButtonOnLeft =
|
||||
!settingsElements['model-info-button-on-left'].checked
|
||||
const removeEmbeddingExtension =
|
||||
!settingsElements['model-add-embedding-extension'].checked
|
||||
const previewThumbnailFormat =
|
||||
settingsElements['model-preview-thumbnail-type'].value
|
||||
const previewThumbnailWidth = Math.round(
|
||||
settingsElements['model-preview-thumbnail-width'].value / 0.75,
|
||||
)
|
||||
const previewThumbnailHeight = Math.round(
|
||||
settingsElements['model-preview-thumbnail-height'].value / 0.75,
|
||||
)
|
||||
const buttonsOnlyOnHover =
|
||||
settingsElements['model-buttons-only-on-hover'].checked
|
||||
if (models.length > 0) {
|
||||
const $overlay = IS_FIREFOX
|
||||
? (modelType, path, removeEmbeddingExtension, strictDragToAdd) => {
|
||||
return $el('div.model-preview-overlay', {
|
||||
ondragstart: (e) => {
|
||||
const data = {
|
||||
modelType: modelType,
|
||||
path: path,
|
||||
removeEmbeddingExtension: removeEmbeddingExtension,
|
||||
strictDragToAdd: strictDragToAdd,
|
||||
}
|
||||
e.dataTransfer.setData('manager-model', JSON.stringify(data))
|
||||
e.dataTransfer.setData('text/plain', '')
|
||||
},
|
||||
draggable: true,
|
||||
})
|
||||
}
|
||||
: (modelType, path, removeEmbeddingExtension, strictDragToAdd) => {
|
||||
return $el('div.model-preview-overlay', {
|
||||
ondragend: (e) =>
|
||||
ModelGrid.dragAddModel(
|
||||
e,
|
||||
modelType,
|
||||
path,
|
||||
removeEmbeddingExtension,
|
||||
strictDragToAdd,
|
||||
),
|
||||
draggable: true,
|
||||
})
|
||||
}
|
||||
const forHiddingButtonsClass = buttonsOnlyOnHover
|
||||
? 'model-buttons-hidden'
|
||||
: 'model-buttons-visible'
|
||||
|
||||
return models.map((item) => {
|
||||
const previewInfo = item.preview
|
||||
const previewThumbnail = $el('img.model-preview', {
|
||||
loading:
|
||||
'lazy' /* `loading` BEFORE `src`; Known bug in Firefox 124.0.2 and Safari for iOS 17.4.1 (https://stackoverflow.com/a/76252772) */,
|
||||
src: imageUri(
|
||||
previewInfo?.path,
|
||||
previewInfo?.dateModified,
|
||||
previewThumbnailWidth,
|
||||
previewThumbnailHeight,
|
||||
previewThumbnailFormat,
|
||||
),
|
||||
draggable: false,
|
||||
})
|
||||
const searchPath = item.path
|
||||
const path = SearchPath.systemPath(
|
||||
searchPath,
|
||||
searchSeparator,
|
||||
systemSeparator,
|
||||
)
|
||||
let actionButtons = []
|
||||
if (showCopyButton) {
|
||||
actionButtons.push(
|
||||
new ComfyButton({
|
||||
icon: 'content-copy',
|
||||
tooltip: 'Copy model to clipboard',
|
||||
classList: 'comfyui-button icon-button model-button',
|
||||
action: (e) =>
|
||||
ModelGrid.#copyModelToClipboard(
|
||||
e,
|
||||
modelType,
|
||||
path,
|
||||
removeEmbeddingExtension,
|
||||
),
|
||||
}).element,
|
||||
)
|
||||
}
|
||||
if (
|
||||
showAddButton &&
|
||||
!(modelType === 'embeddings' && !navigator.clipboard)
|
||||
) {
|
||||
actionButtons.push(
|
||||
new ComfyButton({
|
||||
icon: 'plus-box-outline',
|
||||
tooltip: 'Add model to node grid',
|
||||
classList: 'comfyui-button icon-button model-button',
|
||||
action: (e) =>
|
||||
ModelGrid.#addModel(
|
||||
e,
|
||||
modelType,
|
||||
path,
|
||||
removeEmbeddingExtension,
|
||||
addOffset,
|
||||
),
|
||||
}).element,
|
||||
)
|
||||
}
|
||||
if (showLoadWorkflowButton) {
|
||||
actionButtons.push(
|
||||
new ComfyButton({
|
||||
icon: 'arrow-bottom-left-bold-box-outline',
|
||||
tooltip: 'Load preview workflow',
|
||||
classList: 'comfyui-button icon-button model-button',
|
||||
action: async (e) => {
|
||||
const urlString = previewThumbnail.src
|
||||
const url = new URL(urlString)
|
||||
const urlSearchParams = url.searchParams
|
||||
const uri = urlSearchParams.get('uri')
|
||||
const v = urlSearchParams.get('v')
|
||||
const urlFull =
|
||||
urlString.substring(0, urlString.indexOf('?')) +
|
||||
'?uri=' +
|
||||
uri +
|
||||
'&v=' +
|
||||
v
|
||||
await loadWorkflow(urlFull)
|
||||
},
|
||||
}).element,
|
||||
)
|
||||
}
|
||||
const infoButtons = [
|
||||
new ComfyButton({
|
||||
icon: 'information-outline',
|
||||
tooltip: 'View model information',
|
||||
classList: 'comfyui-button icon-button model-button',
|
||||
action: async () => {
|
||||
await showModelInfo(searchPath)
|
||||
},
|
||||
}).element,
|
||||
]
|
||||
return $el('div.item', {}, [
|
||||
previewThumbnail,
|
||||
$overlay(modelType, path, removeEmbeddingExtension, strictDragToAdd),
|
||||
$el(
|
||||
'div.model-preview-top-right.' + forHiddingButtonsClass,
|
||||
{
|
||||
draggable: false,
|
||||
},
|
||||
modelInfoButtonOnLeft ? infoButtons : actionButtons,
|
||||
),
|
||||
$el(
|
||||
'div.model-preview-top-left.' + forHiddingButtonsClass,
|
||||
{
|
||||
draggable: false,
|
||||
},
|
||||
modelInfoButtonOnLeft ? actionButtons : infoButtons,
|
||||
),
|
||||
$el(
|
||||
'div.model-label',
|
||||
{
|
||||
draggable: false,
|
||||
},
|
||||
[
|
||||
$el('p', [
|
||||
showModelExtension
|
||||
? item.name
|
||||
: SearchPath.splitExtension(item.name)[0],
|
||||
]),
|
||||
],
|
||||
),
|
||||
])
|
||||
})
|
||||
} else {
|
||||
return [$el('h2', ['No Models'])]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLDivElement} modelGrid
|
||||
* @param {ModelData} modelData
|
||||
* @param {HTMLSelectElement} modelSelect
|
||||
* @param {Object.<{value: string}>} previousModelType
|
||||
* @param {Object} settings
|
||||
* @param {string} sortBy
|
||||
* @param {boolean} reverseSort
|
||||
* @param {Array} previousModelFilters
|
||||
* @param {HTMLInputElement} modelFilter
|
||||
* @param {(searchPath: string) => Promise<void>} showModelInfo
|
||||
*/
|
||||
static update(
|
||||
modelGrid,
|
||||
modelData,
|
||||
modelSelect,
|
||||
previousModelType,
|
||||
settings,
|
||||
sortBy,
|
||||
reverseSort,
|
||||
previousModelFilters,
|
||||
modelFilter,
|
||||
showModelInfo,
|
||||
) {
|
||||
const models = modelData.models
|
||||
let modelType = modelSelect.value
|
||||
if (models[modelType] === undefined) {
|
||||
modelType = settings['model-default-browser-model-type'].value
|
||||
}
|
||||
if (models[modelType] === undefined) {
|
||||
modelType = 'checkpoints' // panic fallback
|
||||
}
|
||||
|
||||
if (modelType !== previousModelType.value) {
|
||||
if (settings['model-persistent-search'].checked) {
|
||||
previousModelFilters.splice(0, previousModelFilters.length) // TODO: make sure this actually worked!
|
||||
} else {
|
||||
// cache previous filter text
|
||||
previousModelFilters[previousModelType.value] = modelFilter.value
|
||||
// read cached filter text
|
||||
modelFilter.value = previousModelFilters[modelType] ?? ''
|
||||
}
|
||||
previousModelType.value = modelType
|
||||
}
|
||||
|
||||
let modelTypeOptions = []
|
||||
for (const [key, value] of Object.entries(models)) {
|
||||
const el = $el('option', [key])
|
||||
modelTypeOptions.push(el)
|
||||
}
|
||||
modelSelect.innerHTML = ''
|
||||
modelTypeOptions.forEach((option) => modelSelect.add(option))
|
||||
modelSelect.value = modelType
|
||||
|
||||
const searchAppend = settings['model-search-always-append'].value
|
||||
const searchText = modelFilter.value + ' ' + searchAppend
|
||||
const modelList = ModelGrid.#filter(models[modelType], searchText)
|
||||
ModelGrid.#sort(modelList, sortBy, reverseSort)
|
||||
|
||||
modelGrid.innerHTML = ''
|
||||
const modelGridModels = ModelGrid.#generateInnerHtml(
|
||||
modelList,
|
||||
modelType,
|
||||
settings,
|
||||
modelData.searchSeparator,
|
||||
modelData.systemSeparator,
|
||||
showModelInfo,
|
||||
)
|
||||
modelGrid.append.apply(modelGrid, modelGridModels)
|
||||
}
|
||||
}
|
||||
45
src/utils/model.ts
Normal file
45
src/utils/model.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
const loader = {
|
||||
checkpoints: 'CheckpointLoaderSimple',
|
||||
clip: 'CLIPLoader',
|
||||
clip_vision: 'CLIPVisionLoader',
|
||||
controlnet: 'ControlNetLoader',
|
||||
diffusers: 'DiffusersLoader',
|
||||
diffusion_models: 'DiffusersLoader',
|
||||
embeddings: 'Embedding',
|
||||
gligen: 'GLIGENLoader',
|
||||
hypernetworks: 'HypernetworkLoader',
|
||||
photomaker: 'PhotoMakerLoader',
|
||||
loras: 'LoraLoader',
|
||||
style_models: 'StyleModelLoader',
|
||||
unet: 'UNETLoader',
|
||||
upscale_models: 'UpscaleModelLoader',
|
||||
vae: 'VAELoader',
|
||||
vae_approx: undefined,
|
||||
}
|
||||
|
||||
const display = {
|
||||
all: 'ALL',
|
||||
checkpoints: 'Checkpoint',
|
||||
clip: 'Clip',
|
||||
clip_vision: 'Clip Vision',
|
||||
controlnet: 'Controlnet',
|
||||
diffusers: 'Diffusers',
|
||||
diffusion_models: 'Diffusers',
|
||||
embeddings: 'embedding',
|
||||
gligen: 'Gligen',
|
||||
hypernetworks: 'Hypernetwork',
|
||||
photomaker: 'Photomaker',
|
||||
loras: 'LoRA',
|
||||
style_models: 'Style Model',
|
||||
unet: 'Unet',
|
||||
upscale_models: 'Upscale Model',
|
||||
vae: 'VAE',
|
||||
vae_approx: 'VAE approx',
|
||||
}
|
||||
|
||||
export const resolveModelType = (type: string) => {
|
||||
return {
|
||||
display: display[type],
|
||||
loader: loader[type],
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user