feat: add mini progress circle to progress panel when collapsed

This commit is contained in:
Will Miao
2025-04-30 15:18:18 +08:00
parent 61f723a1f5
commit e1efff19f0
3 changed files with 169 additions and 18 deletions

View File

@@ -25,6 +25,7 @@
.progress-panel.collapsed .progress-panel-header {
border-bottom: none;
padding-bottom: calc(var(--space-2) + 12px);
}
.progress-panel-header {
@@ -61,6 +62,7 @@
justify-content: center;
opacity: 0.6;
transition: all 0.2s;
position: relative;
}
.icon-button:hover {
@@ -165,4 +167,49 @@
.hidden {
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;
}

View File

@@ -9,6 +9,8 @@ class ExampleImagesManager {
this.progressUpdateInterval = null;
this.startTime = null;
this.progressPanel = null;
this.isProgressPanelCollapsed = false;
this.pauseButton = null; // Store reference to the pause button
// Initialize download path field and check download status
this.initializePathOptions();
@@ -23,12 +25,22 @@ class ExampleImagesManager {
// Initialize progress panel reference
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
const pauseBtn = document.getElementById('pauseExampleDownloadBtn');
this.pauseButton = document.getElementById('pauseExampleDownloadBtn');
const collapseBtn = document.getElementById('collapseProgressBtn');
if (pauseBtn) {
pauseBtn.onclick = () => this.pauseDownload();
if (this.pauseButton) {
this.pauseButton.onclick = () => this.pauseDownload();
}
if (collapseBtn) {
@@ -245,8 +257,16 @@ class ExampleImagesManager {
if (data.success) {
this.isPaused = true;
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();
showToast('Download paused', 'info');
} else {
@@ -273,8 +293,16 @@ class ExampleImagesManager {
if (data.success) {
this.isPaused = false;
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();
showToast('Download resumed', 'success');
} else {
@@ -357,6 +385,9 @@ class ExampleImagesManager {
if (progressBar) {
const progressPercent = status.total > 0 ? (status.completed / status.total) * 100 : 0;
progressBar.style.width = `${progressPercent}%`;
// Update mini progress circle
this.updateMiniProgress(progressPercent);
}
// Update current model
@@ -372,21 +403,76 @@ class ExampleImagesManager {
this.updateErrors(status);
// Update pause/resume button
const pauseBtn = document.getElementById('pauseExampleDownloadBtn');
const resumeBtn = document.getElementById('resumeExampleDownloadBtn');
if (!this.pauseButton) {
this.pauseButton = document.getElementById('pauseExampleDownloadBtn');
}
if (pauseBtn) {
if (status.status === 'paused') {
pauseBtn.innerHTML = '<i class="fas fa-play"></i>';
pauseBtn.onclick = () => this.resumeDownload();
if (this.pauseButton) {
// Check if the button already has the SVG elements
let hasProgressElements = !!this.pauseButton.querySelector('.mini-progress-circle');
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 {
pauseBtn.innerHTML = '<i class="fas fa-pause"></i>';
pauseBtn.onclick = () => this.pauseDownload();
// If elements exist, just update the icon
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) {
resumeBtn.style.display = status.status === 'paused' ? 'block' : 'none';
// Query elements within the context of the pause button
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;
}
this.isProgressPanelCollapsed = !this.isProgressPanelCollapsed;
this.progressPanel.classList.toggle('collapsed');
// Save collapsed state to storage
setStorageItem('progress_panel_collapsed', this.isProgressPanelCollapsed);
// Update icon
const icon = document.querySelector('#collapseProgressBtn i');
if (icon) {
if (this.progressPanel.classList.contains('collapsed')) {
if (this.isProgressPanelCollapsed) {
icon.className = 'fas fa-chevron-up';
} else {
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);
}
}
}
}

View File

@@ -7,6 +7,11 @@
<div class="progress-panel-actions">
<button id="pauseExampleDownloadBtn" class="icon-button">
<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 id="collapseProgressBtn" class="icon-button">
<i class="fas fa-chevron-down"></i>