Implement preview version tracking for LoRA cards

This commit is contained in:
Will Miao
2025-02-04 16:19:28 +08:00
parent 9489a1989a
commit 44306e3a8e
4 changed files with 18 additions and 37 deletions

View File

@@ -163,23 +163,28 @@ export async function replacePreview(filePath) {
}
const data = await response.json();
const newPreviewPath = `${data.preview_url}?t=${new Date().getTime()}`;
// 更新预览版本
state.previewVersions.set(filePath, Date.now());
// 更新卡片显示
const card = document.querySelector(`.lora-card[data-filepath="${filePath}"]`);
const previewContainer = card.querySelector('.card-preview');
const oldPreview = previewContainer.querySelector('img, video');
const previewUrl = `${data.preview_url}?t=${state.previewVersions.get(filePath)}`;
if (file.type.startsWith('video/')) {
const video = document.createElement('video');
video.controls = true;
video.autoplay = true;
video.muted = true;
video.loop = true;
video.src = newPreviewPath;
video.src = previewUrl;
oldPreview.replaceWith(video);
} else {
const img = document.createElement('img');
img.src = newPreviewPath;
img.src = previewUrl;
oldPreview.replaceWith(img);
}

View File

@@ -1,5 +1,6 @@
import { showToast } from '../utils/uiHelpers.js';
import { modalManager } from '../managers/ModalManager.js';
import { state } from '../state/index.js';
export function createLoraCard(lora) {
const card = document.createElement('div');
@@ -13,16 +14,17 @@ export function createLoraCard(lora) {
card.dataset.from_civitai = lora.from_civitai;
card.dataset.meta = JSON.stringify(lora.civitai || {});
// Add timestamp to preview URL to prevent caching
const previewUrl = lora.preview_url ? `${lora.preview_url}?t=${Date.now()}` : '/loras_static/images/no-preview.png';
const version = state.previewVersions.get(lora.file_path);
const previewUrl = lora.preview_url || '/loras_static/images/no-preview.png';
const versionedPreviewUrl = version ? `${previewUrl}?t=${version}` : previewUrl;
card.innerHTML = `
<div class="card-preview">
${previewUrl.endsWith('.mp4') ?
`<video controls autoplay muted loop>
<source src="${previewUrl}" type="video/mp4">
<source src="${versionedPreviewUrl}" type="video/mp4">
</video>` :
`<img src="${previewUrl}" alt="${lora.model_name}">`
`<img src="${versionedPreviewUrl}" alt="${lora.model_name}">`
}
<div class="card-header">
<span class="base-model-label" title="${lora.base_model}">
@@ -76,20 +78,6 @@ export function createLoraCard(lora) {
return card;
}
export function updatePreviewInCard(filePath, file, previewUrl) {
const card = document.querySelector(`.lora-card[data-filepath="${filePath}"]`);
const previewContainer = card?.querySelector('.card-preview');
const oldPreview = previewContainer?.querySelector('img, video');
if (oldPreview) {
const newPreviewUrl = `${previewUrl}?t=${Date.now()}`;
const newPreview = file.type.startsWith('video/')
? createVideoPreview(newPreviewUrl)
: createImagePreview(newPreviewUrl);
oldPreview.replaceWith(newPreview);
}
}
export function showLoraModal(lora) {
const escapedWords = lora.trainedWords?.length ?
lora.trainedWords.map(word => word.replace(/'/g, '\\\'')) : [];
@@ -194,17 +182,4 @@ export function initializeLoraCards() {
.catch(() => showToast('Copy failed', 'error'));
});
});
}
function createVideoPreview(url) {
const video = document.createElement('video');
video.controls = video.autoplay = video.muted = video.loop = true;
video.src = url;
return video;
}
function createImagePreview(url) {
const img = document.createElement('img');
img.src = url;
return img;
}
}

View File

@@ -2,7 +2,7 @@ import { debounce } from './utils/debounce.js';
import { LoadingManager } from './managers/LoadingManager.js';
import { modalManager } from './managers/ModalManager.js';
import { state } from './state/index.js';
import { createLoraCard, updatePreviewInCard, showLoraModal, initializeLoraCards } from './components/LoraCard.js';
import { showLoraModal, initializeLoraCards } from './components/LoraCard.js';
import { loadMoreLoras, fetchCivitai, deleteModel, replacePreview, resetAndReload, refreshLoras } from './api/loraApi.js';
import { showToast, lazyLoadImages, restoreFolderFilter, initTheme, toggleTheme, toggleFolder, copyTriggerWord } from './utils/uiHelpers.js';
import { initializeInfiniteScroll } from './utils/infiniteScroll.js';

View File

@@ -5,5 +5,6 @@ export const state = {
sortBy: 'name',
activeFolder: null,
loadingManager: null,
observer: null
observer: null,
previewVersions: new Map()
};