feat: Enhance preview tooltip loading behavior for smoother display

This commit is contained in:
Will Miao
2025-08-24 19:02:08 +08:00
parent e9ada70088
commit a34ade0120
2 changed files with 34 additions and 5 deletions

View File

@@ -256,7 +256,7 @@ class AutoComplete {
const x = rect.right + 10; const x = rect.right + 10;
const y = rect.top; const y = rect.top;
this.previewTooltip.show(loraName, x, y); this.previewTooltip.show(loraName, x, y, true); // Pass true for fromAutocomplete flag
} }
hidePreview() { hidePreview() {

View File

@@ -312,8 +312,6 @@ export class PreviewTooltip {
mediaElement.controls = false; mediaElement.controls = false;
} }
mediaElement.src = data.preview_url;
// Create name label with absolute positioning // Create name label with absolute positioning
const nameLabel = document.createElement('div'); const nameLabel = document.createElement('div');
nameLabel.textContent = loraName; nameLabel.textContent = loraName;
@@ -339,12 +337,43 @@ export class PreviewTooltip {
mediaContainer.appendChild(nameLabel); mediaContainer.appendChild(nameLabel);
this.element.appendChild(mediaContainer); this.element.appendChild(mediaContainer);
// Add fade-in effect // Show element with opacity 0 first to get dimensions
this.element.style.opacity = '0'; this.element.style.opacity = '0';
this.element.style.display = 'block'; this.element.style.display = 'block';
this.position(x, y);
// Wait for media to load before positioning
const waitForLoad = () => {
return new Promise((resolve) => {
if (isVideo) {
if (mediaElement.readyState >= 2) { // HAVE_CURRENT_DATA
resolve();
} else {
mediaElement.addEventListener('loadeddata', resolve, { once: true });
mediaElement.addEventListener('error', resolve, { once: true });
}
} else {
if (mediaElement.complete) {
resolve();
} else {
mediaElement.addEventListener('load', resolve, { once: true });
mediaElement.addEventListener('error', resolve, { once: true });
}
}
// Set a timeout to prevent hanging
setTimeout(resolve, 1000);
});
};
// Set source after setting up load listeners
mediaElement.src = data.preview_url;
// Wait for content to load, then position and show
await waitForLoad();
// Small delay to ensure layout is complete
requestAnimationFrame(() => { requestAnimationFrame(() => {
this.position(x, y);
this.element.style.transition = 'opacity 0.15s ease'; this.element.style.transition = 'opacity 0.15s ease';
this.element.style.opacity = '1'; this.element.style.opacity = '1';
}); });