Prevent metadata transfer UI flicker
This commit is contained in:
@@ -163,6 +163,43 @@ test('metadata transfer persists only mode and activity scope preferences', () =
|
||||
});
|
||||
});
|
||||
|
||||
test('metadata transfer refresh updates only the transfer panel when it is mounted', () => {
|
||||
const state = createTransferState([
|
||||
{ category: 'text_encoders', original_path: 'imported.safetensors' },
|
||||
]);
|
||||
const currentPanel = { outerHTML: '<section class="mr-image-transfer">old</section>' };
|
||||
const result = {
|
||||
querySelector(selector) {
|
||||
assert.equal(selector, '.mr-image-transfer');
|
||||
return currentPanel;
|
||||
},
|
||||
};
|
||||
let fullRenderCount = 0;
|
||||
let tooltipBindCount = 0;
|
||||
const context = {
|
||||
...imageMetadataMethods,
|
||||
imageInspectorState: state,
|
||||
contentElement: {
|
||||
querySelector(selector) {
|
||||
assert.equal(selector, '[data-image-inspector-result]');
|
||||
return result;
|
||||
},
|
||||
},
|
||||
renderMetadataTransferPanel: () => '<section class="mr-image-transfer">updated</section>',
|
||||
renderImageMetadataResult() {
|
||||
fullRenderCount += 1;
|
||||
},
|
||||
bindTooltips() {
|
||||
tooltipBindCount += 1;
|
||||
},
|
||||
};
|
||||
|
||||
assert.equal(context.renderMetadataTransferPanelInPlace(), true);
|
||||
assert.equal(currentPanel.outerHTML, '<section class="mr-image-transfer">updated</section>');
|
||||
assert.equal(fullRenderCount, 0);
|
||||
assert.equal(tooltipBindCount, 1);
|
||||
});
|
||||
|
||||
test('metadata transfer exposes Undo transfer while the post-transfer workflow is unchanged', () => {
|
||||
const context = createTransferContext();
|
||||
const state = createTransferState([
|
||||
@@ -220,7 +257,9 @@ test('metadata transfer undo restores the previous workflow and consumes its his
|
||||
return true;
|
||||
},
|
||||
renderImageMetadataResult() {},
|
||||
openMetadataTransfer() {},
|
||||
openMetadataTransfer() {
|
||||
state.transfer = { undoing: false };
|
||||
},
|
||||
showNotification(message, type) {
|
||||
notifications.push({ message, type });
|
||||
},
|
||||
@@ -241,7 +280,7 @@ test('metadata transfer undo restores the previous workflow and consumes its his
|
||||
assert.deepEqual(restoredWorkflow, previousWorkflow);
|
||||
assert.notEqual(restoredWorkflow, previousWorkflow);
|
||||
assert.equal(context.imageInspectorState.lastTransfer, null);
|
||||
assert.equal(context.imageInspectorState.transfer, null);
|
||||
assert.equal(context.imageInspectorState.transfer.undoing, false);
|
||||
assert.equal(context.activeWorkflowSignature, 'before');
|
||||
assert.equal(context.cachedLoadedModelsSignature, null);
|
||||
assert.equal(context.cachedLoadedModelsData, null);
|
||||
|
||||
@@ -286,14 +286,14 @@ export const imageMetadataMethods = {
|
||||
else delete sourceSelections[selectionKey];
|
||||
}
|
||||
state.transfer.sourceSelections = sourceSelections;
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (input.matches?.('[data-image-transfer-mode]')) {
|
||||
const state = getImageInspectorState(this);
|
||||
if (state.transfer) state.transfer.mode = this.setMetadataTransferMode(input.value);
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
return;
|
||||
}
|
||||
if (input.matches?.('[data-image-transfer-activity-scope]')) {
|
||||
@@ -301,7 +301,7 @@ export const imageMetadataMethods = {
|
||||
if (state.transfer) {
|
||||
state.transfer.activityScope = this.setMetadataTransferActivityScope(input.value);
|
||||
}
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
return;
|
||||
}
|
||||
});
|
||||
@@ -1482,6 +1482,19 @@ export const imageMetadataMethods = {
|
||||
`;
|
||||
},
|
||||
|
||||
renderMetadataTransferPanelInPlace({ fallback = true } = {}) {
|
||||
const result = this.contentElement?.querySelector('[data-image-inspector-result]');
|
||||
const currentPanel = result?.querySelector('.mr-image-transfer');
|
||||
if (!currentPanel) {
|
||||
if (fallback) this.renderImageMetadataResult();
|
||||
return false;
|
||||
}
|
||||
|
||||
currentPanel.outerHTML = this.renderMetadataTransferPanel(getImageInspectorState(this));
|
||||
this.bindTooltips?.(result);
|
||||
return true;
|
||||
},
|
||||
|
||||
async openMetadataTransfer({ force = false, preserveContent = false } = {}) {
|
||||
const state = getImageInspectorState(this);
|
||||
const imageRequestToken = state.requestToken;
|
||||
@@ -1540,14 +1553,13 @@ export const imageMetadataMethods = {
|
||||
state.transfer.targetGroups = Array.isArray(previousTransfer.targetGroups)
|
||||
? previousTransfer.targetGroups
|
||||
: [];
|
||||
} else {
|
||||
this.renderImageMetadataResult();
|
||||
}
|
||||
this.renderMetadataTransferPanelInPlace({ fallback: !keepCurrentTransferContent });
|
||||
|
||||
if (!workflow) {
|
||||
state.transfer.loading = false;
|
||||
state.transfer.error = 'No current workflow is available.';
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1596,7 +1608,7 @@ export const imageMetadataMethods = {
|
||||
Array.from(state.transfer.selectedNodeKeys || [])
|
||||
.filter(nodeKey => selectableNodeKeys.has(nodeKey))
|
||||
);
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
return targetModels;
|
||||
} catch (error) {
|
||||
if (
|
||||
@@ -1606,7 +1618,7 @@ export const imageMetadataMethods = {
|
||||
state.transfer.loading = false;
|
||||
state.transfer.refreshing = false;
|
||||
state.transfer.error = error?.message || 'Could not scan the current workflow.';
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
return null;
|
||||
}
|
||||
},
|
||||
@@ -1615,7 +1627,7 @@ export const imageMetadataMethods = {
|
||||
const state = getImageInspectorState(this);
|
||||
if (!state.transfer) return;
|
||||
state.transfer.selectedNodeKeys = new Set();
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
},
|
||||
|
||||
toggleMetadataTransferCategory(category) {
|
||||
@@ -1628,7 +1640,7 @@ export const imageMetadataMethods = {
|
||||
if (collapsed.has(normalizedCategory)) collapsed.delete(normalizedCategory);
|
||||
else collapsed.add(normalizedCategory);
|
||||
state.transfer.collapsedCategories = collapsed;
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
},
|
||||
|
||||
toggleMetadataTransferNode(nodeKey) {
|
||||
@@ -1656,7 +1668,7 @@ export const imageMetadataMethods = {
|
||||
selected.add(String(nodeKey));
|
||||
}
|
||||
state.transfer.selectedNodeKeys = selected;
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
},
|
||||
|
||||
async undoMetadataTransfer() {
|
||||
@@ -1667,7 +1679,7 @@ export const imageMetadataMethods = {
|
||||
const undoState = this.getMetadataTransferUndoState();
|
||||
if (!undoState.available) {
|
||||
if (undoState.reason) this.showNotification(undoState.reason, 'warning');
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1680,7 +1692,7 @@ export const imageMetadataMethods = {
|
||||
const transfer = state.transfer;
|
||||
lastTransfer.undoing = true;
|
||||
if (transfer) transfer.undoing = true;
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
|
||||
try {
|
||||
const restored = await this.updateWorkflowInComfyUI(restoreWorkflow, []);
|
||||
@@ -1694,9 +1706,7 @@ export const imageMetadataMethods = {
|
||||
|| this.getWorkflowSignature?.(restoreWorkflow)
|
||||
|| null;
|
||||
state.lastTransfer = null;
|
||||
state.transfer = null;
|
||||
this.renderImageMetadataResult();
|
||||
void this.openMetadataTransfer();
|
||||
void this.openMetadataTransfer({ preserveContent: true });
|
||||
this.showNotification('Undid the last model transfer.', 'success');
|
||||
window.dispatchEvent?.(new Event('model-resolver-active-workflowchange'));
|
||||
return restoreWorkflow;
|
||||
@@ -1706,7 +1716,7 @@ export const imageMetadataMethods = {
|
||||
transfer.undoing = false;
|
||||
transfer.error = error?.message || 'The previous workflow could not be restored.';
|
||||
}
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
return null;
|
||||
}
|
||||
},
|
||||
@@ -1714,7 +1724,7 @@ export const imageMetadataMethods = {
|
||||
async applyMetadataTransfer() {
|
||||
const state = getImageInspectorState(this);
|
||||
const transfer = state.transfer;
|
||||
if (!transfer || transfer.loading || transfer.refreshing || transfer.applying) return null;
|
||||
if (!transfer || transfer.loading || transfer.refreshing || transfer.applying || transfer.undoing) return null;
|
||||
const mode = normalizeTransferMode(transfer.mode);
|
||||
const activityScope = normalizeTransferActivityScope(transfer.activityScope);
|
||||
|
||||
@@ -1821,7 +1831,7 @@ export const imageMetadataMethods = {
|
||||
const previousWorkflowSignature = this.getWorkflowSignature?.(workflow) || null;
|
||||
|
||||
transfer.applying = true;
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
try {
|
||||
const data = await this.fetchJson(
|
||||
'/model_resolver/transfer-models',
|
||||
@@ -1858,9 +1868,7 @@ export const imageMetadataMethods = {
|
||||
undoing: false,
|
||||
};
|
||||
this.activeWorkflowSignature = this.getWorkflowSignature?.(updatedWorkflow) || null;
|
||||
state.transfer = null;
|
||||
this.renderImageMetadataResult();
|
||||
void this.openMetadataTransfer();
|
||||
void this.openMetadataTransfer({ preserveContent: true });
|
||||
const updatedCount = Number(data.updated) || 0;
|
||||
const skippedCount = Array.isArray(data.skipped) ? data.skipped.length : 0;
|
||||
const suffix = skippedCount
|
||||
@@ -1876,7 +1884,7 @@ export const imageMetadataMethods = {
|
||||
if (state.transfer) {
|
||||
state.transfer.applying = false;
|
||||
state.transfer.error = error?.message || 'The metadata model transfer failed.';
|
||||
this.renderImageMetadataResult();
|
||||
this.renderMetadataTransferPanelInPlace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user