mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
feat: add mini progress circle to progress panel when collapsed
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
.progress-panel.collapsed .progress-panel-header {
|
.progress-panel.collapsed .progress-panel-header {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
|
padding-bottom: calc(var(--space-2) + 12px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-panel-header {
|
.progress-panel-header {
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-button:hover {
|
.icon-button:hover {
|
||||||
@@ -165,4 +167,49 @@
|
|||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mini progress indicator on pause button when panel collapsed */
|
||||||
|
.mini-progress-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0; /* Hide by default */
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show mini progress when panel is collapsed */
|
||||||
|
.progress-panel.collapsed .mini-progress-container {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mini-progress-circle {
|
||||||
|
stroke: var(--lora-accent);
|
||||||
|
fill: none;
|
||||||
|
stroke-width: 2.5;
|
||||||
|
stroke-linecap: round;
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
transform-origin: center;
|
||||||
|
transition: stroke-dashoffset 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mini-progress-background {
|
||||||
|
stroke: var(--lora-border);
|
||||||
|
fill: none;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-percent {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
font-size: 0.65em;
|
||||||
|
color: var(--text-color);
|
||||||
|
opacity: 0.8;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,8 @@ class ExampleImagesManager {
|
|||||||
this.progressUpdateInterval = null;
|
this.progressUpdateInterval = null;
|
||||||
this.startTime = null;
|
this.startTime = null;
|
||||||
this.progressPanel = null;
|
this.progressPanel = null;
|
||||||
|
this.isProgressPanelCollapsed = false;
|
||||||
|
this.pauseButton = null; // Store reference to the pause button
|
||||||
|
|
||||||
// Initialize download path field and check download status
|
// Initialize download path field and check download status
|
||||||
this.initializePathOptions();
|
this.initializePathOptions();
|
||||||
@@ -23,12 +25,22 @@ class ExampleImagesManager {
|
|||||||
// Initialize progress panel reference
|
// Initialize progress panel reference
|
||||||
this.progressPanel = document.getElementById('exampleImagesProgress');
|
this.progressPanel = document.getElementById('exampleImagesProgress');
|
||||||
|
|
||||||
|
// Load collapse state from storage
|
||||||
|
this.isProgressPanelCollapsed = getStorageItem('progress_panel_collapsed', false);
|
||||||
|
if (this.progressPanel && this.isProgressPanelCollapsed) {
|
||||||
|
this.progressPanel.classList.add('collapsed');
|
||||||
|
const icon = document.querySelector('#collapseProgressBtn i');
|
||||||
|
if (icon) {
|
||||||
|
icon.className = 'fas fa-chevron-up';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize progress panel button handlers
|
// Initialize progress panel button handlers
|
||||||
const pauseBtn = document.getElementById('pauseExampleDownloadBtn');
|
this.pauseButton = document.getElementById('pauseExampleDownloadBtn');
|
||||||
const collapseBtn = document.getElementById('collapseProgressBtn');
|
const collapseBtn = document.getElementById('collapseProgressBtn');
|
||||||
|
|
||||||
if (pauseBtn) {
|
if (this.pauseButton) {
|
||||||
pauseBtn.onclick = () => this.pauseDownload();
|
this.pauseButton.onclick = () => this.pauseDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collapseBtn) {
|
if (collapseBtn) {
|
||||||
@@ -245,8 +257,16 @@ class ExampleImagesManager {
|
|||||||
if (data.success) {
|
if (data.success) {
|
||||||
this.isPaused = true;
|
this.isPaused = true;
|
||||||
document.getElementById('downloadStatusText').textContent = 'Paused';
|
document.getElementById('downloadStatusText').textContent = 'Paused';
|
||||||
document.getElementById('pauseExampleDownloadBtn').innerHTML = '<i class="fas fa-play"></i>';
|
|
||||||
document.getElementById('pauseExampleDownloadBtn').onclick = () => this.resumeDownload();
|
// Only update the icon element, not the entire innerHTML
|
||||||
|
if (this.pauseButton) {
|
||||||
|
const iconElement = this.pauseButton.querySelector('i');
|
||||||
|
if (iconElement) {
|
||||||
|
iconElement.className = 'fas fa-play';
|
||||||
|
}
|
||||||
|
this.pauseButton.onclick = () => this.resumeDownload();
|
||||||
|
}
|
||||||
|
|
||||||
this.updateDownloadButtonText();
|
this.updateDownloadButtonText();
|
||||||
showToast('Download paused', 'info');
|
showToast('Download paused', 'info');
|
||||||
} else {
|
} else {
|
||||||
@@ -273,8 +293,16 @@ class ExampleImagesManager {
|
|||||||
if (data.success) {
|
if (data.success) {
|
||||||
this.isPaused = false;
|
this.isPaused = false;
|
||||||
document.getElementById('downloadStatusText').textContent = 'Downloading';
|
document.getElementById('downloadStatusText').textContent = 'Downloading';
|
||||||
document.getElementById('pauseExampleDownloadBtn').innerHTML = '<i class="fas fa-pause"></i>';
|
|
||||||
document.getElementById('pauseExampleDownloadBtn').onclick = () => this.pauseDownload();
|
// Only update the icon element, not the entire innerHTML
|
||||||
|
if (this.pauseButton) {
|
||||||
|
const iconElement = this.pauseButton.querySelector('i');
|
||||||
|
if (iconElement) {
|
||||||
|
iconElement.className = 'fas fa-pause';
|
||||||
|
}
|
||||||
|
this.pauseButton.onclick = () => this.pauseDownload();
|
||||||
|
}
|
||||||
|
|
||||||
this.updateDownloadButtonText();
|
this.updateDownloadButtonText();
|
||||||
showToast('Download resumed', 'success');
|
showToast('Download resumed', 'success');
|
||||||
} else {
|
} else {
|
||||||
@@ -357,6 +385,9 @@ class ExampleImagesManager {
|
|||||||
if (progressBar) {
|
if (progressBar) {
|
||||||
const progressPercent = status.total > 0 ? (status.completed / status.total) * 100 : 0;
|
const progressPercent = status.total > 0 ? (status.completed / status.total) * 100 : 0;
|
||||||
progressBar.style.width = `${progressPercent}%`;
|
progressBar.style.width = `${progressPercent}%`;
|
||||||
|
|
||||||
|
// Update mini progress circle
|
||||||
|
this.updateMiniProgress(progressPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current model
|
// Update current model
|
||||||
@@ -372,21 +403,76 @@ class ExampleImagesManager {
|
|||||||
this.updateErrors(status);
|
this.updateErrors(status);
|
||||||
|
|
||||||
// Update pause/resume button
|
// Update pause/resume button
|
||||||
const pauseBtn = document.getElementById('pauseExampleDownloadBtn');
|
if (!this.pauseButton) {
|
||||||
const resumeBtn = document.getElementById('resumeExampleDownloadBtn');
|
this.pauseButton = document.getElementById('pauseExampleDownloadBtn');
|
||||||
|
}
|
||||||
|
|
||||||
if (pauseBtn) {
|
if (this.pauseButton) {
|
||||||
if (status.status === 'paused') {
|
// Check if the button already has the SVG elements
|
||||||
pauseBtn.innerHTML = '<i class="fas fa-play"></i>';
|
let hasProgressElements = !!this.pauseButton.querySelector('.mini-progress-circle');
|
||||||
pauseBtn.onclick = () => this.resumeDownload();
|
|
||||||
|
if (!hasProgressElements) {
|
||||||
|
// If elements don't exist, add them
|
||||||
|
this.pauseButton.innerHTML = `
|
||||||
|
<i class="${status.status === 'paused' ? 'fas fa-play' : 'fas fa-pause'}"></i>
|
||||||
|
<svg class="mini-progress-container" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<circle class="mini-progress-background" cx="12" cy="12" r="10"></circle>
|
||||||
|
<circle class="mini-progress-circle" cx="12" cy="12" r="10" stroke-dasharray="62.8" stroke-dashoffset="62.8"></circle>
|
||||||
|
</svg>
|
||||||
|
<span class="progress-percent"></span>
|
||||||
|
`;
|
||||||
} else {
|
} else {
|
||||||
pauseBtn.innerHTML = '<i class="fas fa-pause"></i>';
|
// If elements exist, just update the icon
|
||||||
pauseBtn.onclick = () => this.pauseDownload();
|
const iconElement = this.pauseButton.querySelector('i');
|
||||||
|
if (iconElement) {
|
||||||
|
iconElement.className = status.status === 'paused' ? 'fas fa-play' : 'fas fa-pause';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update click handler
|
||||||
|
this.pauseButton.onclick = status.status === 'paused'
|
||||||
|
? () => this.resumeDownload()
|
||||||
|
: () => this.pauseDownload();
|
||||||
|
|
||||||
|
// Update progress immediately
|
||||||
|
const progressBar = document.getElementById('downloadProgressBar');
|
||||||
|
if (progressBar) {
|
||||||
|
const progressPercent = status.total > 0 ? (status.completed / status.total) * 100 : 0;
|
||||||
|
this.updateMiniProgress(progressPercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the mini progress circle in the pause button
|
||||||
|
updateMiniProgress(percent) {
|
||||||
|
// Ensure we have the pause button reference
|
||||||
|
if (!this.pauseButton) {
|
||||||
|
this.pauseButton = document.getElementById('pauseExampleDownloadBtn');
|
||||||
|
if (!this.pauseButton) {
|
||||||
|
console.error('Pause button not found');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resumeBtn) {
|
// Query elements within the context of the pause button
|
||||||
resumeBtn.style.display = status.status === 'paused' ? 'block' : 'none';
|
const miniProgressCircle = this.pauseButton.querySelector('.mini-progress-circle');
|
||||||
|
const percentText = this.pauseButton.querySelector('.progress-percent');
|
||||||
|
|
||||||
|
if (miniProgressCircle && percentText) {
|
||||||
|
// Circle circumference = 2πr = 2 * π * 10 = 62.8
|
||||||
|
const circumference = 62.8;
|
||||||
|
const offset = circumference - (percent / 100) * circumference;
|
||||||
|
|
||||||
|
miniProgressCircle.style.strokeDashoffset = offset;
|
||||||
|
percentText.textContent = `${Math.round(percent)}%`;
|
||||||
|
|
||||||
|
// Only show percent text when panel is collapsed
|
||||||
|
percentText.style.display = this.isProgressPanelCollapsed ? 'block' : 'none';
|
||||||
|
} else {
|
||||||
|
console.warn('Mini progress elements not found within pause button',
|
||||||
|
this.pauseButton,
|
||||||
|
'mini-progress-circle:', !!miniProgressCircle,
|
||||||
|
'progress-percent:', !!percentText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,17 +571,30 @@ class ExampleImagesManager {
|
|||||||
if (!this.progressPanel) return;
|
if (!this.progressPanel) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isProgressPanelCollapsed = !this.isProgressPanelCollapsed;
|
||||||
this.progressPanel.classList.toggle('collapsed');
|
this.progressPanel.classList.toggle('collapsed');
|
||||||
|
|
||||||
|
// Save collapsed state to storage
|
||||||
|
setStorageItem('progress_panel_collapsed', this.isProgressPanelCollapsed);
|
||||||
|
|
||||||
// Update icon
|
// Update icon
|
||||||
const icon = document.querySelector('#collapseProgressBtn i');
|
const icon = document.querySelector('#collapseProgressBtn i');
|
||||||
if (icon) {
|
if (icon) {
|
||||||
if (this.progressPanel.classList.contains('collapsed')) {
|
if (this.isProgressPanelCollapsed) {
|
||||||
icon.className = 'fas fa-chevron-up';
|
icon.className = 'fas fa-chevron-up';
|
||||||
} else {
|
} else {
|
||||||
icon.className = 'fas fa-chevron-down';
|
icon.className = 'fas fa-chevron-down';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force update mini progress if panel is collapsed
|
||||||
|
if (this.isProgressPanelCollapsed) {
|
||||||
|
const progressBar = document.getElementById('downloadProgressBar');
|
||||||
|
if (progressBar) {
|
||||||
|
const progressPercent = parseFloat(progressBar.style.width) || 0;
|
||||||
|
this.updateMiniProgress(progressPercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,11 @@
|
|||||||
<div class="progress-panel-actions">
|
<div class="progress-panel-actions">
|
||||||
<button id="pauseExampleDownloadBtn" class="icon-button">
|
<button id="pauseExampleDownloadBtn" class="icon-button">
|
||||||
<i class="fas fa-pause"></i>
|
<i class="fas fa-pause"></i>
|
||||||
|
<svg class="mini-progress-container" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<circle class="mini-progress-background" cx="12" cy="12" r="10"></circle>
|
||||||
|
<circle class="mini-progress-circle" cx="12" cy="12" r="10" stroke-dasharray="62.8" stroke-dashoffset="62.8"></circle>
|
||||||
|
</svg>
|
||||||
|
<span class="progress-percent"></span>
|
||||||
</button>
|
</button>
|
||||||
<button id="collapseProgressBtn" class="icon-button">
|
<button id="collapseProgressBtn" class="icon-button">
|
||||||
<i class="fas fa-chevron-down"></i>
|
<i class="fas fa-chevron-down"></i>
|
||||||
|
|||||||
Reference in New Issue
Block a user