From 60d23aa238ed246991d4114ee0553abfff2e276d Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Mon, 13 Oct 2025 19:06:32 +0800 Subject: [PATCH] feat(download): enhance download progress ui with transfer stats --- locales/de.json | 8 ++ locales/en.json | 8 ++ locales/es.json | 8 ++ locales/fr.json | 8 ++ locales/he.json | 8 ++ locales/ja.json | 8 ++ locales/ko.json | 8 ++ locales/ru.json | 8 ++ locales/zh-CN.json | 8 ++ locales/zh-TW.json | 8 ++ static/css/components/loading.css | 19 +++- static/js/managers/DownloadManager.js | 8 +- static/js/managers/LoadingManager.js | 95 ++++++++++++++++++-- static/js/managers/import/DownloadManager.js | 8 +- 14 files changed, 202 insertions(+), 8 deletions(-) diff --git a/locales/de.json b/locales/de.json index 102f8fa7..d96cba50 100644 --- a/locales/de.json +++ b/locales/de.json @@ -637,6 +637,14 @@ "downloadedPreview": "Vorschaubild heruntergeladen", "downloadingFile": "{type}-Datei wird heruntergeladen", "finalizing": "Download wird abgeschlossen..." + }, + "progress": { + "currentFile": "Aktuelle Datei:", + "downloading": "Wird heruntergeladen: {name}", + "transferred": "Heruntergeladen: {downloaded} / {total}", + "transferredSimple": "Heruntergeladen: {downloaded}", + "transferredUnknown": "Heruntergeladen: --", + "speed": "Geschwindigkeit: {speed}" } }, "move": { diff --git a/locales/en.json b/locales/en.json index 59c2f394..bf001265 100644 --- a/locales/en.json +++ b/locales/en.json @@ -637,6 +637,14 @@ "downloadedPreview": "Downloaded preview image", "downloadingFile": "Downloading {type} file", "finalizing": "Finalizing download..." + }, + "progress": { + "currentFile": "Current file:", + "downloading": "Downloading: {name}", + "transferred": "Transferred: {downloaded} / {total}", + "transferredSimple": "Transferred: {downloaded}", + "transferredUnknown": "Transferred: --", + "speed": "Speed: {speed}" } }, "move": { diff --git a/locales/es.json b/locales/es.json index a5511520..bf706254 100644 --- a/locales/es.json +++ b/locales/es.json @@ -637,6 +637,14 @@ "downloadedPreview": "Imagen de vista previa descargada", "downloadingFile": "Descargando archivo de {type}", "finalizing": "Finalizando descarga..." + }, + "progress": { + "currentFile": "Archivo actual:", + "downloading": "Descargando: {name}", + "transferred": "Descargado: {downloaded} / {total}", + "transferredSimple": "Descargado: {downloaded}", + "transferredUnknown": "Descargado: --", + "speed": "Velocidad: {speed}" } }, "move": { diff --git a/locales/fr.json b/locales/fr.json index c3bf37da..c64de794 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -637,6 +637,14 @@ "downloadedPreview": "Image d'aperçu téléchargée", "downloadingFile": "Téléchargement du fichier {type}", "finalizing": "Finalisation du téléchargement..." + }, + "progress": { + "currentFile": "Fichier actuel :", + "downloading": "Téléchargement : {name}", + "transferred": "Téléchargé : {downloaded} / {total}", + "transferredSimple": "Téléchargé : {downloaded}", + "transferredUnknown": "Téléchargé : --", + "speed": "Vitesse : {speed}" } }, "move": { diff --git a/locales/he.json b/locales/he.json index b141fca9..ecc2ade6 100644 --- a/locales/he.json +++ b/locales/he.json @@ -637,6 +637,14 @@ "downloadedPreview": "תמונת תצוגה מקדימה הורדה", "downloadingFile": "מוריד קובץ {type}", "finalizing": "מסיים הורדה..." + }, + "progress": { + "currentFile": "הקובץ הנוכחי:", + "downloading": "מוריד: {name}", + "transferred": "הורד: {downloaded} / {total}", + "transferredSimple": "הורד: {downloaded}", + "transferredUnknown": "הורד: --", + "speed": "מהירות: {speed}" } }, "move": { diff --git a/locales/ja.json b/locales/ja.json index 197d8218..76a71313 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -637,6 +637,14 @@ "downloadedPreview": "プレビュー画像をダウンロードしました", "downloadingFile": "{type}ファイルをダウンロード中", "finalizing": "ダウンロードを完了中..." + }, + "progress": { + "currentFile": "現在のファイル:", + "downloading": "ダウンロード中: {name}", + "transferred": "ダウンロード済み: {downloaded} / {total}", + "transferredSimple": "ダウンロード済み: {downloaded}", + "transferredUnknown": "ダウンロード済み: --", + "speed": "速度: {speed}" } }, "move": { diff --git a/locales/ko.json b/locales/ko.json index 63606bfa..7fb88db8 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -637,6 +637,14 @@ "downloadedPreview": "미리보기 이미지 다운로드됨", "downloadingFile": "{type} 파일 다운로드 중", "finalizing": "다운로드 완료 중..." + }, + "progress": { + "currentFile": "현재 파일:", + "downloading": "다운로드 중: {name}", + "transferred": "다운로드됨: {downloaded} / {total}", + "transferredSimple": "다운로드됨: {downloaded}", + "transferredUnknown": "다운로드됨: --", + "speed": "속도: {speed}" } }, "move": { diff --git a/locales/ru.json b/locales/ru.json index 8b4e9a8c..4b014df9 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -637,6 +637,14 @@ "downloadedPreview": "Превью изображение загружено", "downloadingFile": "Загрузка файла {type}", "finalizing": "Завершение загрузки..." + }, + "progress": { + "currentFile": "Текущий файл:", + "downloading": "Скачивается: {name}", + "transferred": "Скачано: {downloaded} / {total}", + "transferredSimple": "Скачано: {downloaded}", + "transferredUnknown": "Скачано: --", + "speed": "Скорость: {speed}" } }, "move": { diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 0c104212..de3e50c9 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -637,6 +637,14 @@ "downloadedPreview": "预览图片已下载", "downloadingFile": "正在下载 {type} 文件", "finalizing": "正在完成下载..." + }, + "progress": { + "currentFile": "当前文件:", + "downloading": "下载中:{name}", + "transferred": "已下载:{downloaded} / {total}", + "transferredSimple": "已下载:{downloaded}", + "transferredUnknown": "已下载:--", + "speed": "速度:{speed}" } }, "move": { diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 5777ddae..1a7f98fa 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -637,6 +637,14 @@ "downloadedPreview": "已下載預覽圖片", "downloadingFile": "正在下載 {type} 檔案", "finalizing": "完成下載中..." + }, + "progress": { + "currentFile": "目前檔案:", + "downloading": "下載中:{name}", + "transferred": "已下載:{downloaded} / {total}", + "transferredSimple": "已下載:{downloaded}", + "transferredUnknown": "已下載:--", + "speed": "速度:{speed}" } }, "move": { diff --git a/static/css/components/loading.css b/static/css/components/loading.css index 44e29b24..5c898ec5 100644 --- a/static/css/components/loading.css +++ b/static/css/components/loading.css @@ -103,6 +103,23 @@ opacity: 0.7; } +.download-transfer-stats { + margin-top: var(--space-2); + font-size: 0.85rem; + color: var(--text-color); + display: flex; + flex-direction: column; + gap: var(--space-1); +} + +.download-transfer-stats .download-transfer-bytes, +.download-transfer-stats .download-transfer-speed { + display: flex; + align-items: center; + gap: var(--space-1); + white-space: nowrap; +} + @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } @@ -114,4 +131,4 @@ .current-item-bar { transition: none; } -} \ No newline at end of file +} diff --git a/static/js/managers/DownloadManager.js b/static/js/managers/DownloadManager.js index c84e7a5f..091c72d1 100644 --- a/static/js/managers/DownloadManager.js +++ b/static/js/managers/DownloadManager.js @@ -453,7 +453,13 @@ export class DownloadManager { } if (data.status === 'progress' && data.download_id === downloadId) { - updateProgress(data.progress, 0, this.currentVersion.name); + const metrics = { + bytesDownloaded: data.bytes_downloaded, + totalBytes: data.total_bytes, + bytesPerSecond: data.bytes_per_second + }; + + updateProgress(data.progress, 0, this.currentVersion.name, metrics); if (data.progress < 3) { this.loadingManager.setStatus(translate('modals.download.status.preparing')); diff --git a/static/js/managers/LoadingManager.js b/static/js/managers/LoadingManager.js index 924b6d4f..3f8f9c78 100644 --- a/static/js/managers/LoadingManager.js +++ b/static/js/managers/LoadingManager.js @@ -1,3 +1,6 @@ +import { translate } from '../utils/i18nHelpers.js'; +import { formatFileSize } from '../utils/formatters.js'; + // Loading management export class LoadingManager { constructor() { @@ -65,7 +68,7 @@ export class LoadingManager { // Show enhanced progress for downloads showDownloadProgress(totalItems = 1) { - this.show('Preparing download...', 0); + this.show(translate('modals.download.status.preparing', {}, 'Preparing download...'), 0); // Create details container const detailsContainer = this.createDetailsContainer(); @@ -76,7 +79,7 @@ export class LoadingManager { const currentItemLabel = document.createElement('div'); currentItemLabel.className = 'current-item-label'; - currentItemLabel.textContent = 'Current file:'; + currentItemLabel.textContent = translate('modals.download.progress.currentFile', {}, 'Current file:'); const currentItemBar = document.createElement('div'); currentItemBar.className = 'current-item-bar-container'; @@ -105,16 +108,96 @@ export class LoadingManager { // Add current item progress to container detailsContainer.appendChild(currentItemContainer); + + // Create transfer stats container + const transferStats = document.createElement('div'); + transferStats.className = 'download-transfer-stats'; + + const bytesDetail = document.createElement('div'); + bytesDetail.className = 'download-transfer-bytes'; + bytesDetail.textContent = translate( + 'modals.download.progress.transferredUnknown', + {}, + 'Transferred: --' + ); + + const speedDetail = document.createElement('div'); + speedDetail.className = 'download-transfer-speed'; + speedDetail.textContent = translate( + 'modals.download.progress.speed', + { speed: '--' }, + 'Speed: --' + ); + + transferStats.appendChild(bytesDetail); + transferStats.appendChild(speedDetail); + detailsContainer.appendChild(transferStats); + + const formatMetricSize = (value) => { + if (value === undefined || value === null || isNaN(value)) { + return '--'; + } + if (value < 1) { + return '0 B'; + } + return formatFileSize(value); + }; + + const updateTransferStats = (metrics = {}) => { + const { bytesDownloaded, totalBytes, bytesPerSecond } = metrics; + + if (bytesDetail) { + const formattedDownloaded = formatMetricSize(bytesDownloaded); + const formattedTotal = formatMetricSize(totalBytes); + + if (formattedDownloaded === '--' && formattedTotal === '--') { + bytesDetail.textContent = translate( + 'modals.download.progress.transferredUnknown', + {}, + 'Transferred: --' + ); + } else if (formattedTotal === '--') { + bytesDetail.textContent = translate( + 'modals.download.progress.transferredSimple', + { downloaded: formattedDownloaded }, + `Transferred: ${formattedDownloaded}` + ); + } else { + bytesDetail.textContent = translate( + 'modals.download.progress.transferred', + { downloaded: formattedDownloaded, total: formattedTotal }, + `Transferred: ${formattedDownloaded} / ${formattedTotal}` + ); + } + } + + if (speedDetail) { + const formattedSpeed = formatMetricSize(bytesPerSecond); + const displaySpeed = formattedSpeed === '--' ? '--' : `${formattedSpeed}/s`; + speedDetail.textContent = translate( + 'modals.download.progress.speed', + { speed: displaySpeed }, + `Speed: ${displaySpeed}` + ); + } + }; + + // Initialize transfer stats with empty data + updateTransferStats(); // Return update function - return (currentProgress, currentIndex = 0, currentName = '') => { + return (currentProgress, currentIndex = 0, currentName = '', metrics = {}) => { // 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}`; + currentItemLabel.textContent = translate( + 'modals.download.progress.downloading', + { name: currentName }, + `Downloading: ${currentName}` + ); } // Update overall label if multiple items @@ -128,6 +211,8 @@ export class LoadingManager { // Single item, just update main progress this.setProgress(currentProgress); } + + updateTransferStats(metrics); }; } @@ -176,4 +261,4 @@ export class LoadingManager { restoreProgressBar() { this.progressBar.style.display = 'block'; } -} \ No newline at end of file +} diff --git a/static/js/managers/import/DownloadManager.js b/static/js/managers/import/DownloadManager.js index c71e9e31..b8b3a4e4 100644 --- a/static/js/managers/import/DownloadManager.js +++ b/static/js/managers/import/DownloadManager.js @@ -164,7 +164,13 @@ export class DownloadManager { const loraName = currentLora ? currentLora.name : ''; // Update progress display - updateProgress(currentLoraProgress, completedDownloads, loraName); + const metrics = { + bytesDownloaded: data.bytes_downloaded, + totalBytes: data.total_bytes, + bytesPerSecond: data.bytes_per_second + }; + + updateProgress(currentLoraProgress, completedDownloads, loraName, metrics); // Add more detailed status messages based on progress if (currentLoraProgress < 3) {