mirror of
				https://github.com/getgrav/grav-plugin-admin.git
				synced 2025-10-31 02:16:26 +01:00 
			
		
		
		
	smoother progress
This commit is contained in:
		| @@ -606,9 +606,8 @@ class SafeUpgradeManager | ||||
|  | ||||
|         try { | ||||
|             $file = $this->download($package, $timeout); | ||||
|             $this->setProgress('installing', 'Installing update...', 80); | ||||
|             $this->performInstall($file); | ||||
|             $this->setProgress('installing', 'Preparing promotion...', 92); | ||||
|             $this->setProgress('installing', 'Preparing promotion...', null); | ||||
|         } catch (Throwable $e) { | ||||
|             $this->setProgress('error', $e->getMessage(), null); | ||||
|  | ||||
| @@ -620,14 +619,14 @@ class SafeUpgradeManager | ||||
|             $this->tmp = null; | ||||
|         } | ||||
|  | ||||
|         $this->setProgress('finalizing', 'Finalizing upgrade...', 95); | ||||
|         $this->setProgress('finalizing', 'Finalizing upgrade...', null); | ||||
|         $safeUpgrade->clearRecoveryFlag(); | ||||
|         if ($this->recovery && method_exists($this->recovery, 'closeUpgradeWindow')) { | ||||
|             $this->recovery->closeUpgradeWindow(); | ||||
|         } | ||||
|  | ||||
|         $this->ensureExecutablePermissions(); | ||||
|         $this->setProgress('finalizing', 'Finalizing upgrade...', 98); | ||||
|         $this->setProgress('finalizing', 'Finalizing upgrade...', null); | ||||
|  | ||||
|         $manifest = $this->resolveLatestManifest(); | ||||
|  | ||||
| @@ -853,7 +852,7 @@ class SafeUpgradeManager | ||||
|      */ | ||||
|     protected function performInstall(string $zip): void | ||||
|     { | ||||
|         $this->setProgress('installing', 'Unpacking archive...', 82); | ||||
|         $this->setProgress('installing', 'Unpacking update...', null); | ||||
|         $folder = Installer::unZip($zip, $this->tmp . '/zip'); | ||||
|         if ($folder === false) { | ||||
|             throw new RuntimeException(Installer::lastErrorMsg()); | ||||
| @@ -870,9 +869,9 @@ class SafeUpgradeManager | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             $this->setProgress('installing', 'Running installer...', 85); | ||||
|             $this->setProgress('installing', 'Running installer...', null); | ||||
|             $install($zip); | ||||
|             $this->setProgress('installing', 'Verifying files...', 88); | ||||
|             $this->setProgress('installing', 'Verifying files...', null); | ||||
|         } catch (Throwable $e) { | ||||
|             throw new RuntimeException($e->getMessage(), 0, $e); | ||||
|         } | ||||
|   | ||||
| @@ -56,6 +56,8 @@ export default class SafeUpgrade { | ||||
|         this.statusFailures = 0; | ||||
|         this.statusContext = null; | ||||
|         this.statusIdleCount = 0; | ||||
|         this.currentStage = null; | ||||
|         this.stageEnteredAt = 0; | ||||
|         this.directStatusUrl = this.resolveDirectStatusUrl(); | ||||
|         this.preferDirectStatus = !!this.directStatusUrl; | ||||
|  | ||||
| @@ -124,6 +126,8 @@ export default class SafeUpgrade { | ||||
|         this.preferDirectStatus = !!this.directStatusUrl; | ||||
|         this.statusContext = null; | ||||
|         this.statusIdleCount = 0; | ||||
|         this.currentStage = null; | ||||
|         this.stageEnteredAt = 0; | ||||
|         this.renderLoading(); | ||||
|         this.modal.open(); | ||||
|         this.fetchPreflight(); | ||||
| @@ -639,6 +643,11 @@ export default class SafeUpgrade { | ||||
|         } | ||||
|  | ||||
|         const stage = data.stage || 'initializing'; | ||||
|         if (stage !== this.currentStage) { | ||||
|             this.currentStage = stage; | ||||
|             this.stageEnteredAt = Date.now(); | ||||
|         } | ||||
|  | ||||
|         const titleResolver = STAGE_TITLES[stage] || STAGE_TITLES.initializing; | ||||
|         const title = titleResolver(); | ||||
|         let percent = typeof data.percent === 'number' ? data.percent : null; | ||||
| @@ -648,12 +657,16 @@ export default class SafeUpgrade { | ||||
|             if (stage === 'initializing') { return percent !== null ? Math.min(percent, 5) : 5; } | ||||
|             if (stage === 'downloading') { | ||||
|                 if (percent !== null) { | ||||
|                     return Math.min(60, Math.round(10 + (percent * 0.5))); | ||||
|                     return Math.min(20, Math.max(5, Math.round(percent * 0.2))); | ||||
|                 } | ||||
|                 return 25; | ||||
|                 return 12; | ||||
|             } | ||||
|             if (stage === 'installing') { | ||||
|                 return this.computeSmoothPercent(20, 90, 28, percent); | ||||
|             } | ||||
|             if (stage === 'finalizing') { | ||||
|                 return this.computeSmoothPercent(90, 99, 6, percent); | ||||
|             } | ||||
|             if (stage === 'installing') { return percent !== null ? Math.min(Math.max(percent, 80), 94) : 80; } | ||||
|             if (stage === 'finalizing') { return percent !== null ? Math.min(Math.max(percent, 95), 99) : 95; } | ||||
|             if (stage === 'complete') { return 100; } | ||||
|             if (stage === 'error') { return null; } | ||||
|             return percent; | ||||
| @@ -665,11 +678,14 @@ export default class SafeUpgrade { | ||||
|         const statusLine = job && job.status ? `<p class="safe-upgrade-status">${t('SAFE_UPGRADE_JOB_STATUS', 'Status')}: <strong>${job.status.toUpperCase()}</strong>${job.error ? ` — ${job.error}` : ''}</p>` : ''; | ||||
|         const animateBar = stage !== 'complete' && stage !== 'error' && percent !== null; | ||||
|         const barClass = `safe-upgrade-progress-bar${animateBar ? ' is-active' : ''}`; | ||||
|         const detailMessage = stage === 'error' | ||||
|             ? `<p>${data.message || ''}</p>` | ||||
|             : (data.message && stage !== 'installing' && stage !== 'finalizing' ? `<p>${data.message}</p>` : ''); | ||||
|  | ||||
|         this.steps.progress.html(` | ||||
|             <div class="safe-upgrade-progress"> | ||||
|                 <h3>${title}</h3> | ||||
|                 <p>${data.message || ''}</p> | ||||
|                 ${detailMessage} | ||||
|                 ${statusLine} | ||||
|                 ${percentLabel ? `<div class="${barClass}"><span style="width:${percent}%"></span></div><div class="progress-value">${percentLabel}</div>` : ''} | ||||
|             </div> | ||||
| @@ -746,6 +762,23 @@ export default class SafeUpgrade { | ||||
|         this.isPolling = false; | ||||
|         this.clearPollTimer(); | ||||
|     } | ||||
|  | ||||
|     computeSmoothPercent(base, target, durationSeconds, actualPercent) { | ||||
|         const span = target - base; | ||||
|         if (span <= 0) { | ||||
|             return actualPercent !== null ? Math.min(Math.max(actualPercent, base), target) : base; | ||||
|         } | ||||
|  | ||||
|         const elapsed = Math.max(0, (Date.now() - this.stageEnteredAt) / 1000); | ||||
|         const progressRatio = Math.min(1, elapsed / Math.max(durationSeconds, 1)); | ||||
|         let smooth = base + (progressRatio * span); | ||||
|  | ||||
|         if (actualPercent !== null && !Number.isNaN(actualPercent)) { | ||||
|             smooth = Math.max(smooth, Math.min(actualPercent, target)); | ||||
|         } | ||||
|  | ||||
|         return Math.min(smooth, target); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function basename(path) { | ||||
|   | ||||
							
								
								
									
										38
									
								
								themes/grav/js/admin.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								themes/grav/js/admin.min.js
									
									
									
									
										vendored
									
									
								
							| @@ -4612,6 +4612,8 @@ var SafeUpgrade = /*#__PURE__*/function () { | ||||
|     this.statusFailures = 0; | ||||
|     this.statusContext = null; | ||||
|     this.statusIdleCount = 0; | ||||
|     this.currentStage = null; | ||||
|     this.stageEnteredAt = 0; | ||||
|     this.directStatusUrl = this.resolveDirectStatusUrl(); | ||||
|     this.preferDirectStatus = !!this.directStatusUrl; | ||||
|     this.registerEvents(); | ||||
| @@ -4680,6 +4682,8 @@ var SafeUpgrade = /*#__PURE__*/function () { | ||||
|       this.preferDirectStatus = !!this.directStatusUrl; | ||||
|       this.statusContext = null; | ||||
|       this.statusIdleCount = 0; | ||||
|       this.currentStage = null; | ||||
|       this.stageEnteredAt = 0; | ||||
|       this.renderLoading(); | ||||
|       this.modal.open(); | ||||
|       this.fetchPreflight(); | ||||
| @@ -5101,9 +5105,14 @@ var SafeUpgrade = /*#__PURE__*/function () { | ||||
|         return; | ||||
|       } | ||||
|       var stage = data.stage || 'initializing'; | ||||
|       if (stage !== this.currentStage) { | ||||
|         this.currentStage = stage; | ||||
|         this.stageEnteredAt = Date.now(); | ||||
|       } | ||||
|       var titleResolver = STAGE_TITLES[stage] || STAGE_TITLES.initializing; | ||||
|       var title = titleResolver(); | ||||
|       var percent = typeof data.percent === 'number' ? data.percent : null; | ||||
|       var self = this; | ||||
|       var scaledPercent = function scaledPercent() { | ||||
|         if (stage === 'queued') { | ||||
|           return 0; | ||||
| @@ -5113,15 +5122,15 @@ var SafeUpgrade = /*#__PURE__*/function () { | ||||
|         } | ||||
|         if (stage === 'downloading') { | ||||
|           if (percent !== null) { | ||||
|             return Math.min(60, Math.round(10 + percent * 0.5)); | ||||
|             return Math.min(20, Math.max(5, Math.round(percent * 0.2))); | ||||
|           } | ||||
|           return 25; | ||||
|           return 12; | ||||
|         } | ||||
|         if (stage === 'installing') { | ||||
|           return percent !== null ? Math.min(Math.max(percent, 80), 94) : 80; | ||||
|           return self.computeSmoothPercent(20, 90, 28, percent); | ||||
|         } | ||||
|         if (stage === 'finalizing') { | ||||
|           return percent !== null ? Math.min(Math.max(percent, 95), 99) : 95; | ||||
|           return self.computeSmoothPercent(90, 99, 6, percent); | ||||
|         } | ||||
|         if (stage === 'complete') { | ||||
|           return 100; | ||||
| @@ -5136,7 +5145,8 @@ var SafeUpgrade = /*#__PURE__*/function () { | ||||
|       var statusLine = job && job.status ? "<p class=\"safe-upgrade-status\">".concat(t('SAFE_UPGRADE_JOB_STATUS', 'Status'), ": <strong>").concat(job.status.toUpperCase(), "</strong>").concat(job.error ? " — ".concat(job.error) : '', "</p>") : ''; | ||||
|       var animateBar = stage !== 'complete' && stage !== 'error' && percent !== null; | ||||
|       var barClass = "safe-upgrade-progress-bar".concat(animateBar ? ' is-active' : ''); | ||||
|       this.steps.progress.html("\n            <div class=\"safe-upgrade-progress\">\n                <h3>".concat(title, "</h3>\n                <p>").concat(data.message || '', "</p>\n                ").concat(statusLine, "\n                ").concat(percentLabel ? "<div class=\"".concat(barClass, "\"><span style=\"width:").concat(percent, "%\"></span></div><div class=\"progress-value\">").concat(percentLabel, "</div>") : '', "\n            </div>\n        ")); | ||||
|       var detailMessage = stage === 'error' ? "<p>".concat(data.message || '', "</p>") : data.message && stage !== 'installing' && stage !== 'finalizing' ? "<p>".concat(data.message, "</p>") : ''; | ||||
|       this.steps.progress.html("\n            <div class=\"safe-upgrade-progress\">\n                <h3>".concat(title, "</h3>\n                ").concat(detailMessage, "\n                ").concat(statusLine, "\n                ").concat(percentLabel ? "<div class=\"".concat(barClass, "\"><span style=\"width:").concat(percent, "%\"></span></div><div class=\"progress-value\">").concat(percentLabel, "</div>") : '', "\n            </div>\n        ")); | ||||
|       this.switchStep('progress'); | ||||
|       if (stage === 'complete') { | ||||
|         this.renderResult({ | ||||
| @@ -5187,6 +5197,24 @@ var SafeUpgrade = /*#__PURE__*/function () { | ||||
|         _this7.steps[handle].toggleClass('hidden', !isActive); | ||||
|       }); | ||||
|     } | ||||
|   }, { | ||||
|     key: "computeSmoothPercent", | ||||
|     value: function computeSmoothPercent(base, target, durationSeconds, actualPercent) { | ||||
|       var span = target - base; | ||||
|       if (span <= 0) { | ||||
|         if (actualPercent !== null && !Number.isNaN(actualPercent)) { | ||||
|           return Math.min(Math.max(actualPercent, base), target); | ||||
|         } | ||||
|         return base; | ||||
|       } | ||||
|       var elapsed = Math.max(0, (Date.now() - this.stageEnteredAt) / 1000); | ||||
|       var ratio = Math.min(1, elapsed / Math.max(durationSeconds, 1)); | ||||
|       var smooth = base + ratio * span; | ||||
|       if (actualPercent !== null && !Number.isNaN(actualPercent)) { | ||||
|         smooth = Math.max(smooth, Math.min(actualPercent, target)); | ||||
|       } | ||||
|       return Math.min(smooth, target); | ||||
|     } | ||||
|   }, { | ||||
|     key: "stopPolling", | ||||
|     value: function stopPolling() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user