mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 15:15:44 -03:00
Implement enhanced loading progress display in DownloadManager and ImportManager. Introduce detailed progress updates and UI elements for current item and overall progress during downloads. Update LoadingManager to support dynamic progress visualization.
This commit is contained in:
@@ -56,6 +56,53 @@
|
|||||||
transition: width 200ms ease-out;
|
transition: width 200ms ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enhanced progress display */
|
||||||
|
.progress-details-container {
|
||||||
|
margin-top: var(--space-3);
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overall-progress-label {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: var(--space-1);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-item-progress {
|
||||||
|
margin-top: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-item-label {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: var(--space-1);
|
||||||
|
color: var(--text-color);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-item-bar-container {
|
||||||
|
height: 8px;
|
||||||
|
background-color: var(--lora-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: var(--space-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-item-bar {
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--lora-accent);
|
||||||
|
transition: width 200ms ease-out;
|
||||||
|
width: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-item-percent {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--text-color-secondary, var(--text-color));
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% { transform: rotate(0deg); }
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
@@ -63,7 +110,8 @@
|
|||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
.lora-card,
|
.lora-card,
|
||||||
.progress-bar {
|
.progress-bar,
|
||||||
|
.current-item-bar {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,20 +270,38 @@ export class DownloadManager {
|
|||||||
throw new Error('No download URL available');
|
throw new Error('No download URL available');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show loading with progress bar for download
|
// Show enhanced loading with progress details
|
||||||
this.loadingManager.show('Downloading LoRA...', 0);
|
const updateProgress = this.loadingManager.showDownloadProgress(1);
|
||||||
|
updateProgress(0, 0, this.currentVersion.name);
|
||||||
|
|
||||||
// Setup WebSocket for progress updates
|
// Setup WebSocket for progress updates
|
||||||
const wsProtocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
const wsProtocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||||
const ws = new WebSocket(`${wsProtocol}${window.location.host}/ws/fetch-progress`);
|
const ws = new WebSocket(`${wsProtocol}${window.location.host}/ws/fetch-progress`);
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.status === 'progress') {
|
if (data.status === 'progress') {
|
||||||
this.loadingManager.setProgress(data.progress);
|
// Update progress display with current progress
|
||||||
this.loadingManager.setStatus(`Downloading: ${data.progress}%`);
|
updateProgress(data.progress, 0, this.currentVersion.name);
|
||||||
|
|
||||||
|
// Add more detailed status messages based on progress
|
||||||
|
if (data.progress < 3) {
|
||||||
|
this.loadingManager.setStatus(`Preparing download...`);
|
||||||
|
} else if (data.progress === 3) {
|
||||||
|
this.loadingManager.setStatus(`Downloaded preview image`);
|
||||||
|
} else if (data.progress > 3 && data.progress < 100) {
|
||||||
|
this.loadingManager.setStatus(`Downloading LoRA file`);
|
||||||
|
} else {
|
||||||
|
this.loadingManager.setStatus(`Finalizing download...`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ws.onerror = (error) => {
|
||||||
|
console.error('WebSocket error:', error);
|
||||||
|
// Continue with download even if WebSocket fails
|
||||||
|
};
|
||||||
|
|
||||||
// Start download
|
// Start download
|
||||||
const response = await fetch('/api/download-lora', {
|
const response = await fetch('/api/download-lora', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@@ -507,27 +507,56 @@ export class ImportManager {
|
|||||||
const wsProtocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
const wsProtocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||||
const ws = new WebSocket(`${wsProtocol}${window.location.host}/ws/fetch-progress`);
|
const ws = new WebSocket(`${wsProtocol}${window.location.host}/ws/fetch-progress`);
|
||||||
|
|
||||||
// Download missing LoRAs sequentially
|
// Show enhanced loading with progress details for multiple items
|
||||||
this.loadingManager.show('Downloading LoRAs...', 0);
|
const updateProgress = this.loadingManager.showDownloadProgress(this.missingLoras.length);
|
||||||
|
|
||||||
let completedDownloads = 0;
|
let completedDownloads = 0;
|
||||||
|
let currentLoraProgress = 0;
|
||||||
|
|
||||||
|
// Set up progress tracking for current download
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
if (data.status === 'progress') {
|
||||||
|
// Update current LoRA progress
|
||||||
|
currentLoraProgress = data.progress;
|
||||||
|
|
||||||
|
// Get current LoRA name
|
||||||
|
const currentLora = this.missingLoras[completedDownloads];
|
||||||
|
const loraName = currentLora ? currentLora.name : '';
|
||||||
|
|
||||||
|
// Update progress display
|
||||||
|
updateProgress(currentLoraProgress, completedDownloads, loraName);
|
||||||
|
|
||||||
|
// Add more detailed status messages based on progress
|
||||||
|
if (currentLoraProgress < 3) {
|
||||||
|
this.loadingManager.setStatus(
|
||||||
|
`Preparing download for LoRA ${completedDownloads+1}/${this.missingLoras.length}`
|
||||||
|
);
|
||||||
|
} else if (currentLoraProgress === 3) {
|
||||||
|
this.loadingManager.setStatus(
|
||||||
|
`Downloaded preview for LoRA ${completedDownloads+1}/${this.missingLoras.length}`
|
||||||
|
);
|
||||||
|
} else if (currentLoraProgress > 3 && currentLoraProgress < 100) {
|
||||||
|
this.loadingManager.setStatus(
|
||||||
|
`Downloading LoRA ${completedDownloads+1}/${this.missingLoras.length}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.loadingManager.setStatus(
|
||||||
|
`Finalizing LoRA ${completedDownloads+1}/${this.missingLoras.length}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (let i = 0; i < this.missingLoras.length; i++) {
|
for (let i = 0; i < this.missingLoras.length; i++) {
|
||||||
const lora = this.missingLoras[i];
|
const lora = this.missingLoras[i];
|
||||||
|
|
||||||
// Update overall progress
|
// Reset current LoRA progress for new download
|
||||||
this.loadingManager.setStatus(`Downloading LoRA ${i+1}/${this.missingLoras.length}: ${lora.name}`);
|
currentLoraProgress = 0;
|
||||||
|
|
||||||
// Set up progress tracking for current download
|
// Initial status update for new LoRA
|
||||||
ws.onmessage = (event) => {
|
this.loadingManager.setStatus(`Starting download for LoRA ${i+1}/${this.missingLoras.length}`);
|
||||||
const data = JSON.parse(event.data);
|
updateProgress(0, completedDownloads, lora.name);
|
||||||
if (data.status === 'progress') {
|
|
||||||
// Calculate overall progress: completed files + current file progress
|
|
||||||
const overallProgress = Math.floor(
|
|
||||||
(completedDownloads + data.progress/100) / this.missingLoras.length * 100
|
|
||||||
);
|
|
||||||
this.loadingManager.setProgress(overallProgress);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Download the LoRA
|
// Download the LoRA
|
||||||
@@ -547,6 +576,15 @@ export class ImportManager {
|
|||||||
// Continue with next download
|
// Continue with next download
|
||||||
} else {
|
} else {
|
||||||
completedDownloads++;
|
completedDownloads++;
|
||||||
|
|
||||||
|
// Update progress to show completion of current LoRA
|
||||||
|
updateProgress(100, completedDownloads, '');
|
||||||
|
|
||||||
|
if (completedDownloads < this.missingLoras.length) {
|
||||||
|
this.loadingManager.setStatus(
|
||||||
|
`Completed ${completedDownloads}/${this.missingLoras.length} LoRAs. Starting next download...`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (downloadError) {
|
} catch (downloadError) {
|
||||||
console.error(`Error downloading LoRA ${lora.name}:`, downloadError);
|
console.error(`Error downloading LoRA ${lora.name}:`, downloadError);
|
||||||
|
|||||||
@@ -4,17 +4,22 @@ export class LoadingManager {
|
|||||||
this.overlay = document.getElementById('loading-overlay');
|
this.overlay = document.getElementById('loading-overlay');
|
||||||
this.progressBar = this.overlay.querySelector('.progress-bar');
|
this.progressBar = this.overlay.querySelector('.progress-bar');
|
||||||
this.statusText = this.overlay.querySelector('.loading-status');
|
this.statusText = this.overlay.querySelector('.loading-status');
|
||||||
|
this.detailsContainer = null; // Will be created when needed
|
||||||
}
|
}
|
||||||
|
|
||||||
show(message = 'Loading...', progress = 0) {
|
show(message = 'Loading...', progress = 0) {
|
||||||
this.overlay.style.display = 'flex';
|
this.overlay.style.display = 'flex';
|
||||||
this.setProgress(progress);
|
this.setProgress(progress);
|
||||||
this.setStatus(message);
|
this.setStatus(message);
|
||||||
|
|
||||||
|
// Remove any existing details container
|
||||||
|
this.removeDetailsContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
this.overlay.style.display = 'none';
|
this.overlay.style.display = 'none';
|
||||||
this.reset();
|
this.reset();
|
||||||
|
this.removeDetailsContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
setProgress(percent) {
|
setProgress(percent) {
|
||||||
@@ -29,6 +34,101 @@ export class LoadingManager {
|
|||||||
reset() {
|
reset() {
|
||||||
this.setProgress(0);
|
this.setProgress(0);
|
||||||
this.setStatus('');
|
this.setStatus('');
|
||||||
|
this.removeDetailsContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a details container for enhanced progress display
|
||||||
|
createDetailsContainer() {
|
||||||
|
// Remove existing container if any
|
||||||
|
this.removeDetailsContainer();
|
||||||
|
|
||||||
|
// Create new container
|
||||||
|
this.detailsContainer = document.createElement('div');
|
||||||
|
this.detailsContainer.className = 'progress-details-container';
|
||||||
|
|
||||||
|
// Insert after the main progress bar
|
||||||
|
const loadingContent = this.overlay.querySelector('.loading-content');
|
||||||
|
if (loadingContent) {
|
||||||
|
loadingContent.appendChild(this.detailsContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.detailsContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove details container
|
||||||
|
removeDetailsContainer() {
|
||||||
|
if (this.detailsContainer) {
|
||||||
|
this.detailsContainer.remove();
|
||||||
|
this.detailsContainer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show enhanced progress for downloads
|
||||||
|
showDownloadProgress(totalItems = 1) {
|
||||||
|
this.show('Preparing download...', 0);
|
||||||
|
|
||||||
|
// Create details container
|
||||||
|
const detailsContainer = this.createDetailsContainer();
|
||||||
|
|
||||||
|
// Create current item progress
|
||||||
|
const currentItemContainer = document.createElement('div');
|
||||||
|
currentItemContainer.className = 'current-item-progress';
|
||||||
|
|
||||||
|
const currentItemLabel = document.createElement('div');
|
||||||
|
currentItemLabel.className = 'current-item-label';
|
||||||
|
currentItemLabel.textContent = 'Current file:';
|
||||||
|
|
||||||
|
const currentItemBar = document.createElement('div');
|
||||||
|
currentItemBar.className = 'current-item-bar-container';
|
||||||
|
|
||||||
|
const currentItemProgress = document.createElement('div');
|
||||||
|
currentItemProgress.className = 'current-item-bar';
|
||||||
|
currentItemProgress.style.width = '0%';
|
||||||
|
|
||||||
|
const currentItemPercent = document.createElement('span');
|
||||||
|
currentItemPercent.className = 'current-item-percent';
|
||||||
|
currentItemPercent.textContent = '0%';
|
||||||
|
|
||||||
|
currentItemBar.appendChild(currentItemProgress);
|
||||||
|
currentItemContainer.appendChild(currentItemLabel);
|
||||||
|
currentItemContainer.appendChild(currentItemBar);
|
||||||
|
currentItemContainer.appendChild(currentItemPercent);
|
||||||
|
|
||||||
|
// Create overall progress elements if multiple items
|
||||||
|
let overallLabel = null;
|
||||||
|
if (totalItems > 1) {
|
||||||
|
overallLabel = document.createElement('div');
|
||||||
|
overallLabel.className = 'overall-progress-label';
|
||||||
|
overallLabel.textContent = `Overall progress (0/${totalItems} complete):`;
|
||||||
|
detailsContainer.appendChild(overallLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add current item progress to container
|
||||||
|
detailsContainer.appendChild(currentItemContainer);
|
||||||
|
|
||||||
|
// Return update function
|
||||||
|
return (currentProgress, currentIndex = 0, currentName = '') => {
|
||||||
|
// Update current item progress
|
||||||
|
currentItemProgress.style.width = `${currentProgress}%`;
|
||||||
|
currentItemPercent.textContent = `${Math.floor(currentProgress)}%`;
|
||||||
|
|
||||||
|
// Update current item label if name provided
|
||||||
|
if (currentName) {
|
||||||
|
currentItemLabel.textContent = `Downloading: ${currentName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update overall label if multiple items
|
||||||
|
if (totalItems > 1 && overallLabel) {
|
||||||
|
overallLabel.textContent = `Overall progress (${currentIndex}/${totalItems} complete):`;
|
||||||
|
|
||||||
|
// Calculate and update overall progress
|
||||||
|
const overallProgress = Math.floor((currentIndex + currentProgress/100) / totalItems * 100);
|
||||||
|
this.setProgress(overallProgress);
|
||||||
|
} else {
|
||||||
|
// Single item, just update main progress
|
||||||
|
this.setProgress(currentProgress);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async showWithProgress(callback, options = {}) {
|
async showWithProgress(callback, options = {}) {
|
||||||
|
|||||||
Reference in New Issue
Block a user