fix(settings): prevent library modal focus jump

This commit is contained in:
Will Miao
2026-04-11 16:20:37 +08:00
parent 1817142a7b
commit 5f1bd894b9
2 changed files with 49 additions and 3 deletions

View File

@@ -1443,12 +1443,12 @@ export class SettingsManager {
// Add empty row for new path if no paths exist // Add empty row for new path if no paths exist
if (paths.length === 0) { if (paths.length === 0) {
this.addExtraFolderPathRow(modelType, ''); this.addExtraFolderPathRow(modelType, '', false);
} }
}); });
} }
addExtraFolderPathRow(modelType, path = '') { addExtraFolderPathRow(modelType, path = '', shouldFocus = true) {
const container = document.getElementById(`extraFolderPaths-${modelType}`); const container = document.getElementById(`extraFolderPaths-${modelType}`);
if (!container) return; if (!container) return;
@@ -1472,7 +1472,7 @@ export class SettingsManager {
container.appendChild(row); container.appendChild(row);
// Focus the input if it's empty (new row) // Focus the input if it's empty (new row)
if (!path) { if (!path && shouldFocus) {
const input = row.querySelector('.extra-folder-path-input'); const input = row.querySelector('.extra-folder-path-input');
if (input) { if (input) {
setTimeout(() => input.focus(), 0); setTimeout(() => input.focus(), 0);

View File

@@ -96,6 +96,7 @@ beforeEach(() => {
}); });
afterEach(() => { afterEach(() => {
vi.useRealTimers();
delete global.fetch; delete global.fetch;
delete document.hidden; delete document.hidden;
Object.defineProperty(window, 'location', { Object.defineProperty(window, 'location', {
@@ -231,6 +232,51 @@ describe('SettingsManager library controls', () => {
expect(input.value).toBe('/custom/recipes'); expect(input.value).toBe('/custom/recipes');
}); });
it('does not autofocus empty extra folder path rows during initial settings load', async () => {
vi.useFakeTimers();
const manager = createManager();
document.body.innerHTML = `
<div id="extraFolderPaths-loras"></div>
<div id="extraFolderPaths-checkpoints"></div>
<div id="extraFolderPaths-unet"></div>
<div id="extraFolderPaths-embeddings"></div>
`;
vi.spyOn(manager, 'loadMetadataArchiveSettings').mockResolvedValue();
vi.spyOn(manager, 'loadBackupSettings').mockResolvedValue();
vi.spyOn(manager, 'loadLibraries').mockResolvedValue();
vi.spyOn(manager, 'loadLoraRoots').mockResolvedValue();
vi.spyOn(manager, 'loadCheckpointRoots').mockResolvedValue();
vi.spyOn(manager, 'loadUnetRoots').mockResolvedValue();
vi.spyOn(manager, 'loadEmbeddingRoots').mockResolvedValue();
const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus').mockImplementation(() => {});
state.global.settings = {
extra_folder_paths: {},
};
await manager.loadSettingsToUI();
await vi.runAllTimersAsync();
expect(focusSpy).not.toHaveBeenCalled();
});
it('still focuses an extra folder path row when it is added explicitly', async () => {
vi.useFakeTimers();
const manager = createManager();
document.body.innerHTML = '<div id="extraFolderPaths-embeddings"></div>';
const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus').mockImplementation(() => {});
manager.addExtraFolderPathRow('embeddings', '');
await vi.runAllTimersAsync();
expect(focusSpy).toHaveBeenCalledTimes(1);
});
it('shows loading while saving recipes_path', async () => { it('shows loading while saving recipes_path', async () => {
const manager = createManager(); const manager = createManager();
const input = document.createElement('input'); const input = document.createElement('input');