Fix progress polling hover state regression in downloads tab
This commit is contained in:
@@ -4259,6 +4259,45 @@ test('progress polling explicitly handles cancelling as a non-interactive state'
|
||||
);
|
||||
});
|
||||
|
||||
test('Missing Models download progress preserves hovered controls between polling updates', () => {
|
||||
const renderDownloadSnapshot = extractMethod(
|
||||
resolveDownloadMethodsSource,
|
||||
'renderDownloadSnapshot'
|
||||
);
|
||||
const renderDownloadProgressGroupForMissing = extractMethod(
|
||||
resolveDownloadMethodsSource,
|
||||
'renderDownloadProgressGroupForMissing'
|
||||
);
|
||||
const patchDownloadProgressContent = extractMethod(
|
||||
resolveDownloadMethodsSource,
|
||||
'patchDownloadProgressContent'
|
||||
);
|
||||
const pollDownloadProgress = extractMethod(
|
||||
resolveDownloadMethodsSource,
|
||||
'pollDownloadProgress'
|
||||
);
|
||||
|
||||
assert.match(renderDownloadSnapshot, /patchDownloadProgressContent\(/);
|
||||
assert.doesNotMatch(renderDownloadSnapshot, /progressDiv\.innerHTML\s*=/);
|
||||
assert.match(renderDownloadProgressGroupForMissing, /patchDownloadProgressContent\(/);
|
||||
assert.doesNotMatch(renderDownloadProgressGroupForMissing, /progressDiv\.innerHTML\s*=/);
|
||||
assert.match(
|
||||
patchDownloadProgressContent,
|
||||
/patchDownloadsPanelElement\(progressDiv,\s*nextProgressDiv\)/
|
||||
);
|
||||
|
||||
const activeProgressBranch = pollDownloadProgress.match(
|
||||
/if \(progress\.status === 'downloading'[\s\S]*?\} else if \(progress\.status === 'cancelling'\)/
|
||||
)?.[0] || '';
|
||||
const cancellingBranch = pollDownloadProgress.match(
|
||||
/else if \(progress\.status === 'cancelling'\)[\s\S]*?\} else if \(progress\.status === 'completed'\)/
|
||||
)?.[0] || '';
|
||||
assert.ok(activeProgressBranch);
|
||||
assert.ok(cancellingBranch);
|
||||
assert.doesNotMatch(activeProgressBranch, /refreshLocalMatchesUiForMissing/);
|
||||
assert.doesNotMatch(cancellingBranch, /refreshLocalMatchesUiForMissing/);
|
||||
});
|
||||
|
||||
test('native Xet progress polling refreshes every 200 milliseconds', () => {
|
||||
const getDownloadProgressPollDelay = eval(`(${extractMethod(resolveDownloadMethodsSource, 'getDownloadProgressPollDelay')})`);
|
||||
|
||||
|
||||
@@ -1253,6 +1253,25 @@ export const resolveDownloadMethods = {
|
||||
`;
|
||||
},
|
||||
|
||||
patchDownloadProgressContent(progressDiv, html) {
|
||||
if (!progressDiv) return;
|
||||
|
||||
const nextHtml = String(html || '');
|
||||
if (
|
||||
typeof progressDiv.cloneNode !== 'function'
|
||||
|| typeof this.patchDownloadsPanelElement !== 'function'
|
||||
) {
|
||||
if (progressDiv.innerHTML !== nextHtml) {
|
||||
progressDiv.innerHTML = nextHtml;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const nextProgressDiv = progressDiv.cloneNode(false);
|
||||
nextProgressDiv.innerHTML = nextHtml;
|
||||
this.patchDownloadsPanelElement(progressDiv, nextProgressDiv);
|
||||
},
|
||||
|
||||
renderDownloadProgressGroupForMissing(missing, progressDiv, { includeDownloadId = '', includeSnapshot = null } = {}) {
|
||||
if (!missing || !progressDiv) return false;
|
||||
|
||||
@@ -1271,11 +1290,24 @@ export const resolveDownloadMethods = {
|
||||
|
||||
progressDiv.classList.remove('mr-is-hidden');
|
||||
progressDiv.classList.add('mr-is-visible');
|
||||
progressDiv.innerHTML = `<div class="mr-download-progress-list">${items.join('')}</div>`;
|
||||
this.patchDownloadProgressContent(
|
||||
progressDiv,
|
||||
`<div class="mr-download-progress-list">${items.join('')}</div>`
|
||||
);
|
||||
this.attachDownloadActionHandlers(progressDiv, includeDownloadId);
|
||||
return true;
|
||||
},
|
||||
|
||||
ensureSearchDownloadButtonIcon(downloadBtn) {
|
||||
if (
|
||||
!downloadBtn?.classList?.contains('search-download-btn')
|
||||
|| downloadBtn.querySelector?.('svg')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
downloadBtn.innerHTML = getSvgIcon('download');
|
||||
},
|
||||
|
||||
updateDownloadButtonForSnapshot(downloadBtn, progress, status, shouldRenderProgress) {
|
||||
if (!downloadBtn) return;
|
||||
|
||||
@@ -1293,7 +1325,7 @@ export const resolveDownloadMethods = {
|
||||
? `Paused ${percentLabel}`.trim()
|
||||
: (percentLabel ? `Downloading ${percentLabel}` : 'Starting download...'));
|
||||
if (downloadBtn.classList.contains('search-download-btn')) {
|
||||
downloadBtn.innerHTML = getSvgIcon('download');
|
||||
this.ensureSearchDownloadButtonIcon(downloadBtn);
|
||||
downloadBtn.setAttribute('data-tooltip', label);
|
||||
downloadBtn.setAttribute('aria-label', label);
|
||||
} else {
|
||||
@@ -1307,7 +1339,7 @@ export const resolveDownloadMethods = {
|
||||
downloadBtn.disabled = true;
|
||||
downloadBtn.classList.remove('mr-is-success-action', 'mr-btn-primary');
|
||||
if (downloadBtn.classList.contains('search-download-btn')) {
|
||||
downloadBtn.innerHTML = getSvgIcon('download');
|
||||
this.ensureSearchDownloadButtonIcon(downloadBtn);
|
||||
downloadBtn.setAttribute('data-tooltip', 'Cancelling download...');
|
||||
downloadBtn.setAttribute('aria-label', 'Cancelling download');
|
||||
} else {
|
||||
@@ -1317,7 +1349,7 @@ export const resolveDownloadMethods = {
|
||||
downloadBtn.disabled = false;
|
||||
downloadBtn.classList.remove('mr-is-success-action', 'mr-btn-primary');
|
||||
if (downloadBtn.classList.contains('search-download-btn')) {
|
||||
downloadBtn.innerHTML = getSvgIcon('download');
|
||||
this.ensureSearchDownloadButtonIcon(downloadBtn);
|
||||
downloadBtn.setAttribute('data-tooltip', 'Retry download');
|
||||
downloadBtn.setAttribute('aria-label', 'Retry download');
|
||||
} else {
|
||||
@@ -1354,7 +1386,10 @@ export const resolveDownloadMethods = {
|
||||
if (progressDiv) {
|
||||
progressDiv.classList.remove('mr-is-hidden');
|
||||
progressDiv.classList.add('mr-is-visible');
|
||||
progressDiv.innerHTML = this.renderDownloadSnapshotMarkup(downloadId, snapshot);
|
||||
this.patchDownloadProgressContent(
|
||||
progressDiv,
|
||||
this.renderDownloadSnapshotMarkup(downloadId, snapshot)
|
||||
);
|
||||
this.attachDownloadActionHandlers(progressDiv, downloadId);
|
||||
}
|
||||
|
||||
@@ -1873,7 +1908,6 @@ export const resolveDownloadMethods = {
|
||||
|
||||
if (progress.status === 'downloading' || progress.status === 'starting' || progress.status === 'paused') {
|
||||
this.renderDownloadSnapshot(downloadId, snapshot, { progressDiv, downloadBtn });
|
||||
this.refreshLocalMatchesUiForMissing?.(missing);
|
||||
if (typeof this.requestQueuePanelUpdate === 'function') {
|
||||
this.requestQueuePanelUpdate();
|
||||
} else {
|
||||
@@ -1886,7 +1920,6 @@ export const resolveDownloadMethods = {
|
||||
|
||||
} else if (progress.status === 'cancelling') {
|
||||
this.renderDownloadSnapshot(downloadId, snapshot, { progressDiv, downloadBtn });
|
||||
this.refreshLocalMatchesUiForMissing?.(missing);
|
||||
this.updateQueuePanel?.();
|
||||
setTimeout(() => this.pollDownloadProgress(downloadId), 500);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user