Enhance CivitAI metadata fetch handling and update virtual scroller item management. See #227

This commit is contained in:
Will Miao
2025-06-15 08:34:22 +08:00
parent 672fbe2ac0
commit 78bcdcef5d
7 changed files with 72 additions and 15 deletions

View File

@@ -10,7 +10,6 @@ from ..nodes.utils import get_lora_info
from ..config import config
from ..services.websocket_manager import ws_manager
from ..services.settings_manager import settings
import asyncio
from .update_routes import UpdateRoutes
from ..utils.constants import PREVIEW_EXTENSIONS, CARD_PREVIEW_WIDTH, VALID_LORA_TYPES
@@ -107,7 +106,21 @@ class ApiRoutes:
"""Handle CivitAI metadata fetch request"""
if self.scanner is None:
self.scanner = await ServiceRegistry.get_lora_scanner()
return await ModelRouteUtils.handle_fetch_civitai(request, self.scanner)
response = await ModelRouteUtils.handle_fetch_civitai(request, self.scanner)
# If successful, format the metadata before returning
if response.status == 200:
data = json.loads(response.body.decode('utf-8'))
if data.get("success") and data.get("metadata"):
formatted_metadata = self._format_lora_response(data["metadata"])
return web.json_response({
"success": True,
"metadata": formatted_metadata
})
# Otherwise, return the original response
return response
async def replace_preview(self, request: web.Request) -> web.Response:
"""Handle preview image replacement request"""

View File

@@ -521,7 +521,20 @@ class CheckpointsRoutes:
async def fetch_civitai(self, request: web.Request) -> web.Response:
"""Handle CivitAI metadata fetch request for checkpoints"""
return await ModelRouteUtils.handle_fetch_civitai(request, self.scanner)
response = await ModelRouteUtils.handle_fetch_civitai(request, self.scanner)
# If successful, format the metadata before returning
if response.status == 200:
data = json.loads(response.body.decode('utf-8'))
if data.get("success") and data.get("metadata"):
formatted_metadata = self._format_checkpoint_response(data["metadata"])
return web.json_response({
"success": True,
"metadata": formatted_metadata
})
# Otherwise, return the original response
return response
async def replace_preview(self, request: web.Request) -> web.Response:
"""Handle preview image replacement for checkpoints"""

View File

@@ -332,7 +332,7 @@ class ModelRouteUtils:
scanner: The model scanner instance with cache management methods
Returns:
web.Response: The HTTP response
web.Response: The HTTP response with metadata on success
"""
try:
data = await request.json()
@@ -357,7 +357,8 @@ class ModelRouteUtils:
# Update the cache
await scanner.update_single_model_cache(data['file_path'], data['file_path'], local_metadata)
return web.json_response({"success": True})
# Return the updated metadata along with success status
return web.json_response({"success": True, "metadata": local_metadata})
finally:
await client.close()

View File

@@ -471,6 +471,11 @@ export async function refreshSingleModelMetadata(filePath, modelType = 'lora') {
const data = await response.json();
if (data.success) {
// Use the returned metadata to update just this single item
if (data.metadata && state.virtualScroller) {
state.virtualScroller.updateSingleItem(filePath, data.metadata);
}
showToast('Metadata refreshed successfully', 'success');
return true;
} else {

View File

@@ -81,11 +81,7 @@ export async function fetchCivitai() {
// Refresh single checkpoint metadata
export async function refreshSingleCheckpointMetadata(filePath) {
const success = await refreshSingleModelMetadata(filePath, 'checkpoint');
if (success) {
// Reload the current view to show updated data
await resetAndReload();
}
await refreshSingleModelMetadata(filePath, 'checkpoint');
}
/**

View File

@@ -117,11 +117,7 @@ export async function refreshLoras(fullRebuild = false) {
}
export async function refreshSingleLoraMetadata(filePath) {
const success = await refreshSingleModelMetadata(filePath, 'lora');
if (success) {
// Reload the current view to show updated data
await resetAndReload();
}
await refreshSingleModelMetadata(filePath, 'lora');
}
export async function fetchModelDescription(modelId, filePath) {

View File

@@ -796,6 +796,39 @@ export class VirtualScroller {
console.log('Virtual scroller enabled');
}
updateSingleItem(filePath, updatedItem) {
if (!filePath || !updatedItem) {
console.error('Invalid parameters for updateSingleItem');
return false;
}
// Find the index of the item with the matching file_path
const index = this.items.findIndex(item => item.file_path === filePath);
if (index === -1) {
console.warn(`Item with file path ${filePath} not found in virtual scroller data`);
return false;
}
// Update the item data
this.items[index] = {...this.items[index], ...updatedItem};
// If the item is currently rendered, update its DOM representation
if (this.renderedItems.has(index)) {
const element = this.renderedItems.get(index);
// Remove the old element
element.remove();
this.renderedItems.delete(index);
// Create and render the updated element
const updatedElement = this.createItemElement(this.items[index], index);
this.renderedItems.set(index, updatedElement);
this.gridElement.appendChild(updatedElement);
}
return true;
}
// New method to remove an item by file path
removeItemByFilePath(filePath) {
if (!filePath || this.disabled || this.items.length === 0) return false;