From 06632728f0640366001e39be41f90ef1576d3ef3 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 18 Oct 2025 18:16:44 -0600 Subject: [PATCH] fixes for progress bar --- themes/grav/app/updates/safe-upgrade.js | 37 +++++++++++++++++++------ themes/grav/js/admin.min.js | 35 +++++++++++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/themes/grav/app/updates/safe-upgrade.js b/themes/grav/app/updates/safe-upgrade.js index 83cc2f23..9b18a6c2 100644 --- a/themes/grav/app/updates/safe-upgrade.js +++ b/themes/grav/app/updates/safe-upgrade.js @@ -64,6 +64,7 @@ export default class SafeUpgrade { this.directStatusUrl = this.resolveDirectStatusUrl(); this.preferDirectStatus = !!this.directStatusUrl; this.modalLocked = false; + this.lastOverallPercent = 0; this.registerEvents(); } @@ -150,6 +151,7 @@ export default class SafeUpgrade { this.currentStage = null; this.stageEnteredAt = 0; this.modalLocked = false; + this.lastOverallPercent = 0; this.renderLoading(); this.modal.open(); this.fetchPreflight(); @@ -501,6 +503,7 @@ export default class SafeUpgrade { startUpgrade() { this.switchStep('progress'); + this.lastOverallPercent = 0; this.renderProgress({ stage: 'initializing', message: t('SAFE_UPGRADE_STAGE_INITIALIZING', 'Preparing upgrade'), @@ -801,24 +804,21 @@ export default class SafeUpgrade { const scaledPercent = () => { if (stage === 'queued') { return 0; } - if (stage === 'initializing') { return percent !== null ? Math.min(percent, 5) : 5; } + if (stage === 'initializing') { return percent !== null ? Math.min(Math.max(percent, 0), 5) : 5; } if (stage === 'downloading') { - if (percent !== null) { - return Math.min(20, Math.max(5, Math.round(percent * 0.2))); - } - return 12; + return this.scaleStagePercent(5, 45, percent, 2); } if (stage === 'snapshot') { - return this.computeSmoothPercent(20, 45, 8, percent); + return this.scaleStagePercent(45, 70, percent, 2); } if (stage === 'installing') { - return this.computeSmoothPercent(20, 90, 28, percent); + return this.scaleStagePercent(70, 95, percent, 3); } if (stage === 'rollback') { - return this.computeSmoothPercent(40, 95, 20, percent); + return this.scaleStagePercent(40, 95, percent, 3); } if (stage === 'finalizing') { - return this.computeSmoothPercent(90, 99, 6, percent); + return this.scaleStagePercent(95, 99, percent, 1.5); } if (stage === 'complete') { return 100; } if (stage === 'error') { return null; } @@ -826,6 +826,11 @@ export default class SafeUpgrade { }; percent = scaledPercent(); + if (percent !== null) { + const baseline = typeof this.lastOverallPercent === 'number' ? this.lastOverallPercent : 0; + percent = Math.max(percent, baseline); + this.lastOverallPercent = percent; + } const displayPercent = percent !== null ? Math.round(percent) : null; const percentLabel = displayPercent !== null ? `${displayPercent}%` : ''; @@ -954,6 +959,20 @@ export default class SafeUpgrade { this.clearPollTimer(); } + scaleStagePercent(start, end, stagePercent, fallbackSeconds) { + const safeStart = typeof start === 'number' ? start : 0; + const safeEnd = typeof end === 'number' ? end : safeStart; + + if (stagePercent !== null && !Number.isNaN(stagePercent)) { + const normalized = Math.min(100, Math.max(0, stagePercent)); + return safeStart + ((safeEnd - safeStart) * normalized) / 100; + } + + const duration = typeof fallbackSeconds === 'number' ? Math.max(fallbackSeconds, 0.25) : 1; + + return this.computeSmoothPercent(safeStart, safeEnd, duration, stagePercent); + } + computeSmoothPercent(base, target, durationSeconds, actualPercent) { const span = target - base; if (span <= 0) { diff --git a/themes/grav/js/admin.min.js b/themes/grav/js/admin.min.js index 3f1dce23..44e7d338 100644 --- a/themes/grav/js/admin.min.js +++ b/themes/grav/js/admin.min.js @@ -2281,6 +2281,7 @@ var SafeUpgrade = /*#__PURE__*/function () { this.directStatusUrl = this.resolveDirectStatusUrl(); this.preferDirectStatus = !!this.directStatusUrl; this.modalLocked = false; + this.lastOverallPercent = 0; this.registerEvents(); } return safe_upgrade_createClass(SafeUpgrade, [{ @@ -2367,6 +2368,7 @@ var SafeUpgrade = /*#__PURE__*/function () { this.currentStage = null; this.stageEnteredAt = 0; this.modalLocked = false; + this.lastOverallPercent = 0; this.renderLoading(); this.modal.open(); this.fetchPreflight(); @@ -2571,6 +2573,7 @@ var SafeUpgrade = /*#__PURE__*/function () { value: function startUpgrade() { var _this4 = this; this.switchStep('progress'); + this.lastOverallPercent = 0; this.renderProgress({ stage: 'initializing', message: t('SAFE_UPGRADE_STAGE_INITIALIZING', 'Preparing upgrade'), @@ -2859,25 +2862,22 @@ var SafeUpgrade = /*#__PURE__*/function () { return 0; } if (stage === 'initializing') { - return percent !== null ? Math.min(percent, 5) : 5; + return percent !== null ? Math.min(Math.max(percent, 0), 5) : 5; } if (stage === 'downloading') { - if (percent !== null) { - return Math.min(20, Math.max(5, Math.round(percent * 0.2))); - } - return 12; + return _this7.scaleStagePercent(5, 45, percent, 2); } if (stage === 'snapshot') { - return _this7.computeSmoothPercent(20, 45, 8, percent); + return _this7.scaleStagePercent(45, 70, percent, 2); } if (stage === 'installing') { - return _this7.computeSmoothPercent(20, 90, 28, percent); + return _this7.scaleStagePercent(70, 95, percent, 3); } if (stage === 'rollback') { - return _this7.computeSmoothPercent(40, 95, 20, percent); + return _this7.scaleStagePercent(40, 95, percent, 3); } if (stage === 'finalizing') { - return _this7.computeSmoothPercent(90, 99, 6, percent); + return _this7.scaleStagePercent(95, 99, percent, 1.5); } if (stage === 'complete') { return 100; @@ -2888,6 +2888,11 @@ var SafeUpgrade = /*#__PURE__*/function () { return percent; }; percent = scaledPercent(); + if (percent !== null) { + var baseline = typeof this.lastOverallPercent === 'number' ? this.lastOverallPercent : 0; + percent = Math.max(percent, baseline); + this.lastOverallPercent = percent; + } var displayPercent = percent !== null ? Math.round(percent) : null; var percentLabel = displayPercent !== null ? "".concat(displayPercent, "%") : ''; var message = typeof data.message === 'string' ? data.message : ''; @@ -2979,6 +2984,18 @@ var SafeUpgrade = /*#__PURE__*/function () { this.isPolling = false; this.clearPollTimer(); } + }, { + key: "scaleStagePercent", + value: function scaleStagePercent(start, end, stagePercent, fallbackSeconds) { + var safeStart = typeof start === 'number' ? start : 0; + var safeEnd = typeof end === 'number' ? end : safeStart; + if (stagePercent !== null && !Number.isNaN(stagePercent)) { + var normalized = Math.min(100, Math.max(0, stagePercent)); + return safeStart + (safeEnd - safeStart) * normalized / 100; + } + var duration = typeof fallbackSeconds === 'number' ? Math.max(fallbackSeconds, 0.25) : 1; + return this.computeSmoothPercent(safeStart, safeEnd, duration, stagePercent); + } }, { key: "computeSmoothPercent", value: function computeSmoothPercent(base, target, durationSeconds, actualPercent) {