mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-24 22:52:12 -03:00
refactor: update model type references from 'lora' to 'loras' and streamline event delegation setup
This commit is contained in:
@@ -153,7 +153,7 @@ async function toggleFavorite(card) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleSendToWorkflow(card, replaceMode, modelType) {
|
function handleSendToWorkflow(card, replaceMode, modelType) {
|
||||||
if (modelType === 'lora') {
|
if (modelType === 'loras') {
|
||||||
const usageTips = JSON.parse(card.dataset.usage_tips || '{}');
|
const usageTips = JSON.parse(card.dataset.usage_tips || '{}');
|
||||||
const strength = usageTips.strength || 1;
|
const strength = usageTips.strength || 1;
|
||||||
const loraSyntax = `<lora:${card.dataset.file_name}:${strength}>`;
|
const loraSyntax = `<lora:${card.dataset.file_name}:${strength}>`;
|
||||||
@@ -165,15 +165,18 @@ function handleSendToWorkflow(card, replaceMode, modelType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleCopyAction(card, modelType) {
|
function handleCopyAction(card, modelType) {
|
||||||
if (modelType === 'lora') {
|
if (modelType === 'loras') {
|
||||||
const usageTips = JSON.parse(card.dataset.usage_tips || '{}');
|
const usageTips = JSON.parse(card.dataset.usage_tips || '{}');
|
||||||
const strength = usageTips.strength || 1;
|
const strength = usageTips.strength || 1;
|
||||||
const loraSyntax = `<lora:${card.dataset.file_name}:${strength}>`;
|
const loraSyntax = `<lora:${card.dataset.file_name}:${strength}>`;
|
||||||
copyToClipboard(loraSyntax, 'LoRA syntax copied to clipboard');
|
copyToClipboard(loraSyntax, 'LoRA syntax copied to clipboard');
|
||||||
} else {
|
} else if (modelType === 'checkpoints') {
|
||||||
// Checkpoint copy functionality - copy checkpoint name
|
// Checkpoint copy functionality - copy checkpoint name
|
||||||
const checkpointName = card.dataset.file_name;
|
const checkpointName = card.dataset.file_name;
|
||||||
copyToClipboard(checkpointName, 'Checkpoint name copied');
|
copyToClipboard(checkpointName, 'Checkpoint name copied');
|
||||||
|
} else if (modelType === 'embeddings') {
|
||||||
|
const embeddingName = card.dataset.file_name;
|
||||||
|
copyToClipboard(embeddingName, 'Embedding name copied');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +219,7 @@ function handleCardClick(card, modelType) {
|
|||||||
|
|
||||||
function showModelModalFromCard(card, modelType) {
|
function showModelModalFromCard(card, modelType) {
|
||||||
// Get the appropriate preview versions map
|
// Get the appropriate preview versions map
|
||||||
const previewVersionsKey = modelType === 'lora' ? 'loras' : 'checkpoints';
|
const previewVersionsKey = modelType;
|
||||||
const previewVersions = state.pages[previewVersionsKey]?.previewVersions || new Map();
|
const previewVersions = state.pages[previewVersionsKey]?.previewVersions || new Map();
|
||||||
const version = previewVersions.get(card.dataset.filepath);
|
const version = previewVersions.get(card.dataset.filepath);
|
||||||
const previewUrl = card.dataset.preview_url || '/loras_static/images/no-preview.png';
|
const previewUrl = card.dataset.preview_url || '/loras_static/images/no-preview.png';
|
||||||
@@ -371,11 +374,11 @@ export function createModelCard(model, modelType) {
|
|||||||
card.dataset.file_size = model.file_size;
|
card.dataset.file_size = model.file_size;
|
||||||
card.dataset.from_civitai = model.from_civitai;
|
card.dataset.from_civitai = model.from_civitai;
|
||||||
card.dataset.notes = model.notes || '';
|
card.dataset.notes = model.notes || '';
|
||||||
card.dataset.base_model = model.base_model || (modelType === 'checkpoint' ? 'Unknown' : '');
|
card.dataset.base_model = model.base_model || 'Unknown';
|
||||||
card.dataset.favorite = model.favorite ? 'true' : 'false';
|
card.dataset.favorite = model.favorite ? 'true' : 'false';
|
||||||
|
|
||||||
// LoRA specific data
|
// LoRA specific data
|
||||||
if (modelType === 'lora') {
|
if (modelType === 'loras') {
|
||||||
card.dataset.usage_tips = model.usage_tips;
|
card.dataset.usage_tips = model.usage_tips;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,12 +407,12 @@ export function createModelCard(model, modelType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply selection state if in bulk mode and this card is in the selected set (LoRA only)
|
// Apply selection state if in bulk mode and this card is in the selected set (LoRA only)
|
||||||
if (modelType === 'lora' && state.bulkMode && state.selectedLoras.has(model.file_path)) {
|
if (modelType === 'loras' && state.bulkMode && state.selectedLoras.has(model.file_path)) {
|
||||||
card.classList.add('selected');
|
card.classList.add('selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the appropriate preview versions map
|
// Get the appropriate preview versions map
|
||||||
const previewVersionsKey = modelType === 'lora' ? 'loras' : 'checkpoints';
|
const previewVersionsKey = modelType;
|
||||||
const previewVersions = state.pages[previewVersionsKey]?.previewVersions || new Map();
|
const previewVersions = state.pages[previewVersionsKey]?.previewVersions || new Map();
|
||||||
const version = previewVersions.get(model.file_path);
|
const version = previewVersions.get(model.file_path);
|
||||||
const previewUrl = model.preview_url || '/loras_static/images/no-preview.png';
|
const previewUrl = model.preview_url || '/loras_static/images/no-preview.png';
|
||||||
@@ -434,8 +437,8 @@ export function createModelCard(model, modelType) {
|
|||||||
const isFavorite = model.favorite === true;
|
const isFavorite = model.favorite === true;
|
||||||
|
|
||||||
// Generate action icons based on model type
|
// Generate action icons based on model type
|
||||||
const actionIcons = modelType === 'lora' ?
|
const actionIcons = `
|
||||||
`<i class="${isFavorite ? 'fas fa-star favorite-active' : 'far fa-star'}"
|
<i class="${isFavorite ? 'fas fa-star favorite-active' : 'far fa-star'}"
|
||||||
title="${isFavorite ? 'Remove from favorites' : 'Add to favorites'}">
|
title="${isFavorite ? 'Remove from favorites' : 'Add to favorites'}">
|
||||||
</i>
|
</i>
|
||||||
<i class="fas fa-globe"
|
<i class="fas fa-globe"
|
||||||
@@ -447,19 +450,6 @@ export function createModelCard(model, modelType) {
|
|||||||
</i>
|
</i>
|
||||||
<i class="fas fa-copy"
|
<i class="fas fa-copy"
|
||||||
title="Copy LoRA Syntax">
|
title="Copy LoRA Syntax">
|
||||||
</i>` :
|
|
||||||
`<i class="${isFavorite ? 'fas fa-star favorite-active' : 'far fa-star'}"
|
|
||||||
title="${isFavorite ? 'Remove from favorites' : 'Add to favorites'}">
|
|
||||||
</i>
|
|
||||||
<i class="fas fa-globe"
|
|
||||||
title="${model.from_civitai ? 'View on Civitai' : 'Not available from Civitai'}"
|
|
||||||
${!model.from_civitai ? 'style="opacity: 0.5; cursor: not-allowed"' : ''}>
|
|
||||||
</i>
|
|
||||||
<i class="fas fa-paper-plane"
|
|
||||||
title="Send to workflow - feature to be implemented">
|
|
||||||
</i>
|
|
||||||
<i class="fas fa-copy"
|
|
||||||
title="Copy Checkpoint Name">
|
|
||||||
</i>`;
|
</i>`;
|
||||||
|
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
|
|||||||
@@ -40,65 +40,4 @@ export function setupTabSwitching() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load model description - General version supports both LoRA and Checkpoint
|
|
||||||
* @param {string} modelId - Model ID
|
|
||||||
* @param {string} filePath - File path
|
|
||||||
*/
|
|
||||||
export async function loadModelDescription(modelId, filePath) {
|
|
||||||
try {
|
|
||||||
const descriptionContainer = document.querySelector('.model-description-content');
|
|
||||||
const loadingElement = document.querySelector('.model-description-loading');
|
|
||||||
|
|
||||||
if (!descriptionContainer || !loadingElement) return;
|
|
||||||
|
|
||||||
// Show loading indicator
|
|
||||||
loadingElement.classList.remove('hidden');
|
|
||||||
descriptionContainer.classList.add('hidden');
|
|
||||||
|
|
||||||
// Determine API endpoint based on file path or context
|
|
||||||
let apiEndpoint = `/api/loras/model-description?model_id=${modelId}&file_path=${encodeURIComponent(filePath)}`;
|
|
||||||
|
|
||||||
// Try to get model description from API
|
|
||||||
const response = await fetch(apiEndpoint);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to fetch model description: ${response.statusText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (data.success && data.description) {
|
|
||||||
// Update the description content
|
|
||||||
descriptionContainer.innerHTML = data.description;
|
|
||||||
|
|
||||||
// Process any links in the description to open in new tab
|
|
||||||
const links = descriptionContainer.querySelectorAll('a');
|
|
||||||
links.forEach(link => {
|
|
||||||
link.setAttribute('target', '_blank');
|
|
||||||
link.setAttribute('rel', 'noopener noreferrer');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show the description and hide loading indicator
|
|
||||||
descriptionContainer.classList.remove('hidden');
|
|
||||||
loadingElement.classList.add('hidden');
|
|
||||||
} else {
|
|
||||||
throw new Error(data.error || 'No description available');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading model description:', error);
|
|
||||||
const loadingElement = document.querySelector('.model-description-loading');
|
|
||||||
if (loadingElement) {
|
|
||||||
loadingElement.innerHTML = `<div class="error-message">Failed to load model description. ${error.message}</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show empty state message in the description container
|
|
||||||
const descriptionContainer = document.querySelector('.model-description-content');
|
|
||||||
if (descriptionContainer) {
|
|
||||||
descriptionContainer.innerHTML = '<div class="no-description">No model description available</div>';
|
|
||||||
descriptionContainer.classList.remove('hidden');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
scrollToTop,
|
scrollToTop,
|
||||||
loadExampleImages
|
loadExampleImages
|
||||||
} from './showcase/ShowcaseView.js';
|
} from './showcase/ShowcaseView.js';
|
||||||
import { setupTabSwitching, loadModelDescription } from './ModelDescription.js';
|
import { setupTabSwitching } from './ModelDescription.js';
|
||||||
import {
|
import {
|
||||||
setupModelNameEditing,
|
setupModelNameEditing,
|
||||||
setupBaseModelEditing,
|
setupBaseModelEditing,
|
||||||
@@ -29,21 +29,21 @@ export function showModelModal(model, modelType) {
|
|||||||
const modalTitle = model.model_name;
|
const modalTitle = model.model_name;
|
||||||
|
|
||||||
// Prepare LoRA specific data
|
// Prepare LoRA specific data
|
||||||
const escapedWords = modelType === 'lora' && model.civitai?.trainedWords?.length ?
|
const escapedWords = (modelType === 'loras' || modelType === 'embeddings') && model.civitai?.trainedWords?.length ?
|
||||||
model.civitai.trainedWords.map(word => word.replace(/'/g, '\\\'')) : [];
|
model.civitai.trainedWords.map(word => word.replace(/'/g, '\\\'')) : [];
|
||||||
|
|
||||||
// Generate model type specific content
|
// Generate model type specific content
|
||||||
const typeSpecificContent = modelType === 'lora' ? renderLoraSpecificContent(model, escapedWords) : '';
|
const typeSpecificContent = modelType === 'loras' ? renderLoraSpecificContent(model, escapedWords) : '';
|
||||||
|
|
||||||
// Generate tabs based on model type
|
// Generate tabs based on model type
|
||||||
const tabsContent = modelType === 'lora' ?
|
const tabsContent = modelType === 'loras' ?
|
||||||
`<button class="tab-btn active" data-tab="showcase">Examples</button>
|
`<button class="tab-btn active" data-tab="showcase">Examples</button>
|
||||||
<button class="tab-btn" data-tab="description">Model Description</button>
|
<button class="tab-btn" data-tab="description">Model Description</button>
|
||||||
<button class="tab-btn" data-tab="recipes">Recipes</button>` :
|
<button class="tab-btn" data-tab="recipes">Recipes</button>` :
|
||||||
`<button class="tab-btn active" data-tab="showcase">Examples</button>
|
`<button class="tab-btn active" data-tab="showcase">Examples</button>
|
||||||
<button class="tab-btn" data-tab="description">Model Description</button>`;
|
<button class="tab-btn" data-tab="description">Model Description</button>`;
|
||||||
|
|
||||||
const tabPanesContent = modelType === 'lora' ?
|
const tabPanesContent = modelType === 'loras' ?
|
||||||
`<div id="showcase-tab" class="tab-pane active">
|
`<div id="showcase-tab" class="tab-pane active">
|
||||||
<div class="example-images-loading">
|
<div class="example-images-loading">
|
||||||
<i class="fas fa-spinner fa-spin"></i> Loading example images...
|
<i class="fas fa-spinner fa-spin"></i> Loading example images...
|
||||||
@@ -143,7 +143,7 @@ export function showModelModal(model, modelType) {
|
|||||||
<div class="base-wrapper">
|
<div class="base-wrapper">
|
||||||
<label>Base Model</label>
|
<label>Base Model</label>
|
||||||
<div class="base-model-display">
|
<div class="base-model-display">
|
||||||
<span class="base-model-content">${model.base_model || (modelType === 'checkpoint' ? 'Unknown' : 'N/A')}</span>
|
<span class="base-model-content">${model.base_model || 'Unknown'}</span>
|
||||||
<button class="edit-base-model-btn" title="Edit base model">
|
<button class="edit-base-model-btn" title="Edit base model">
|
||||||
<i class="fas fa-pencil-alt"></i>
|
<i class="fas fa-pencil-alt"></i>
|
||||||
</button>
|
</button>
|
||||||
@@ -206,16 +206,13 @@ export function showModelModal(model, modelType) {
|
|||||||
setupEventHandlers(model.file_path);
|
setupEventHandlers(model.file_path);
|
||||||
|
|
||||||
// LoRA specific setup
|
// LoRA specific setup
|
||||||
if (modelType === 'lora') {
|
if (modelType === 'loras' || modelType === 'embeddings') {
|
||||||
setupTriggerWordsEditMode();
|
setupTriggerWordsEditMode();
|
||||||
|
|
||||||
// Load recipes for this LoRA
|
if (modelType == 'loras') {
|
||||||
loadRecipesForLora(model.model_name, model.sha256);
|
// Load recipes for this LoRA
|
||||||
}
|
loadRecipesForLora(model.model_name, model.sha256);
|
||||||
|
}
|
||||||
// If we have a model ID but no description, fetch it
|
|
||||||
if (model.civitai?.modelId && !model.modelDescription) {
|
|
||||||
loadModelDescription(model.civitai.modelId, model.file_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load example images asynchronously - merge regular and custom images
|
// Load example images asynchronously - merge regular and custom images
|
||||||
@@ -297,7 +294,7 @@ function setupEventHandlers(filePath) {
|
|||||||
/**
|
/**
|
||||||
* Set up editable fields (notes and usage tips) in the model modal
|
* Set up editable fields (notes and usage tips) in the model modal
|
||||||
* @param {string} filePath - The full file path of the model
|
* @param {string} filePath - The full file path of the model
|
||||||
* @param {string} modelType - Type of model ('lora' or 'checkpoint')
|
* @param {string} modelType - Type of model ('loras' or 'checkpoints' or 'embeddings')
|
||||||
*/
|
*/
|
||||||
function setupEditableFields(filePath, modelType) {
|
function setupEditableFields(filePath, modelType) {
|
||||||
const editableFields = document.querySelectorAll('.editable-field [contenteditable]');
|
const editableFields = document.querySelectorAll('.editable-field [contenteditable]');
|
||||||
@@ -328,13 +325,13 @@ function setupEditableFields(filePath, modelType) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await saveNotes(filePath, modelType);
|
await saveNotes(filePath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoRA specific field setup
|
// LoRA specific field setup
|
||||||
if (modelType === 'lora') {
|
if (modelType === 'loras') {
|
||||||
setupLoraSpecificFields(filePath);
|
setupLoraSpecificFields(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,9 +395,8 @@ function setupLoraSpecificFields(filePath) {
|
|||||||
/**
|
/**
|
||||||
* Save model notes
|
* Save model notes
|
||||||
* @param {string} filePath - Path to the model file
|
* @param {string} filePath - Path to the model file
|
||||||
* @param {string} modelType - Type of model ('lora' or 'checkpoint')
|
|
||||||
*/
|
*/
|
||||||
async function saveNotes(filePath, modelType) {
|
async function saveNotes(filePath) {
|
||||||
const content = document.querySelector('.notes-content').textContent;
|
const content = document.querySelector('.notes-content').textContent;
|
||||||
try {
|
try {
|
||||||
await getModelApiClient().saveModelMetadata(filePath, { notes: content });
|
await getModelApiClient().saveModelMetadata(filePath, { notes: content });
|
||||||
@@ -418,35 +414,4 @@ const modelModal = {
|
|||||||
scrollToTop
|
scrollToTop
|
||||||
};
|
};
|
||||||
|
|
||||||
export { modelModal };
|
export { modelModal };
|
||||||
|
|
||||||
// Define global functions for use in HTML
|
|
||||||
window.toggleShowcase = function(element) {
|
|
||||||
toggleShowcase(element);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.scrollToTopModel = function(button) {
|
|
||||||
scrollToTop(button);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Legacy global functions for backward compatibility
|
|
||||||
window.scrollToTopLora = function(button) {
|
|
||||||
scrollToTop(button);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.scrollToTopCheckpoint = function(button) {
|
|
||||||
scrollToTop(button);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.saveModelNotes = function(filePath, modelType) {
|
|
||||||
saveNotes(filePath, modelType);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Legacy functions
|
|
||||||
window.saveLoraNotes = function(filePath) {
|
|
||||||
saveNotes(filePath, 'lora');
|
|
||||||
};
|
|
||||||
|
|
||||||
window.saveCheckpointNotes = function(filePath) {
|
|
||||||
saveNotes(filePath, 'checkpoint');
|
|
||||||
};
|
|
||||||
@@ -112,7 +112,7 @@ export function renderShowcaseContent(images, exampleFiles = [], startExpanded =
|
|||||||
</div>` : '';
|
</div>` : '';
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="scroll-indicator" onclick="toggleShowcase(this)">
|
<div class="scroll-indicator">
|
||||||
<i class="fas fa-chevron-${startExpanded ? 'up' : 'down'}"></i>
|
<i class="fas fa-chevron-${startExpanded ? 'up' : 'down'}"></i>
|
||||||
<span>Scroll or click to ${startExpanded ? 'hide' : 'show'} ${filteredImages.length} examples</span>
|
<span>Scroll or click to ${startExpanded ? 'hide' : 'show'} ${filteredImages.length} examples</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -479,6 +479,16 @@ export function initShowcaseContent(carousel) {
|
|||||||
initMetadataPanelHandlers(carousel);
|
initMetadataPanelHandlers(carousel);
|
||||||
initMediaControlHandlers(carousel);
|
initMediaControlHandlers(carousel);
|
||||||
positionAllMediaControls(carousel);
|
positionAllMediaControls(carousel);
|
||||||
|
|
||||||
|
// Bind scroll-indicator click to toggleShowcase
|
||||||
|
const scrollIndicator = carousel.previousElementSibling;
|
||||||
|
if (scrollIndicator && scrollIndicator.classList.contains('scroll-indicator')) {
|
||||||
|
// Remove previous click listeners to avoid duplicates
|
||||||
|
scrollIndicator.onclick = null;
|
||||||
|
scrollIndicator.removeEventListener('click', scrollIndicator._toggleShowcaseHandler);
|
||||||
|
scrollIndicator._toggleShowcaseHandler = () => toggleShowcase(scrollIndicator);
|
||||||
|
scrollIndicator.addEventListener('click', scrollIndicator._toggleShowcaseHandler);
|
||||||
|
}
|
||||||
|
|
||||||
// Add window resize handler
|
// Add window resize handler
|
||||||
const resizeHandler = () => positionAllMediaControls(carousel);
|
const resizeHandler = () => positionAllMediaControls(carousel);
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import { showToast } from './uiHelpers.js';
|
|||||||
|
|
||||||
// Function to dynamically import the appropriate card creator based on page type
|
// Function to dynamically import the appropriate card creator based on page type
|
||||||
async function getCardCreator(pageType) {
|
async function getCardCreator(pageType) {
|
||||||
if (pageType === 'loras') {
|
if (pageType === 'recipes') {
|
||||||
return (model) => createModelCard(model, 'lora');
|
|
||||||
} else if (pageType === 'recipes') {
|
|
||||||
// Import the RecipeCard module
|
// Import the RecipeCard module
|
||||||
const { RecipeCard } = await import('../components/RecipeCard.js');
|
const { RecipeCard } = await import('../components/RecipeCard.js');
|
||||||
|
|
||||||
@@ -21,12 +19,11 @@ async function getCardCreator(pageType) {
|
|||||||
});
|
});
|
||||||
return recipeCard.element;
|
return recipeCard.element;
|
||||||
};
|
};
|
||||||
} else if (pageType === 'checkpoints') {
|
|
||||||
return (model) => createModelCard(model, 'checkpoint');
|
|
||||||
} else if (pageType === 'embeddings') {
|
|
||||||
return (model) => createModelCard(model, 'embedding');
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
// For other page types, use the shared ModelCard creator
|
||||||
|
return (model) => createModelCard(model, pageType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to get the appropriate data fetcher based on page type
|
// Function to get the appropriate data fetcher based on page type
|
||||||
@@ -63,14 +60,8 @@ export async function initializeInfiniteScroll(pageType = 'loras') {
|
|||||||
// Use virtual scrolling for all page types
|
// Use virtual scrolling for all page types
|
||||||
await initializeVirtualScroll(pageType);
|
await initializeVirtualScroll(pageType);
|
||||||
|
|
||||||
// Setup event delegation for lora cards if on the loras page
|
// Setup event delegation for model cards based on page type
|
||||||
if (pageType === 'loras') {
|
setupModelCardEventDelegation(pageType);
|
||||||
setupModelCardEventDelegation('lora');
|
|
||||||
} else if (pageType === 'checkpoints') {
|
|
||||||
setupModelCardEventDelegation('checkpoint');
|
|
||||||
} else if (pageType === 'embeddings') {
|
|
||||||
setupModelCardEventDelegation('embedding');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initializeVirtualScroll(pageType) {
|
async function initializeVirtualScroll(pageType) {
|
||||||
|
|||||||
Reference in New Issue
Block a user