mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-08-07 06:20:15 -03:00
feat(recipes): wire recipes layout switch event and rebuild
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { showToast } from '../utils/uiHelpers.js';
|
||||
import { RecipeCard } from './RecipeCard.js';
|
||||
import { state, getCurrentPageState } from '../state/index.js';
|
||||
import { recreateVirtualScroll } from '../utils/infiniteScroll.js';
|
||||
|
||||
export class DuplicatesManager {
|
||||
constructor(recipeManager) {
|
||||
@@ -96,6 +97,12 @@ export class DuplicatesManager {
|
||||
|
||||
// Re-enable virtual scrolling
|
||||
state.virtualScroller.enable();
|
||||
|
||||
// Apply a layout switch that was deferred while duplicates mode was active
|
||||
if (state.pendingLayoutRecreate) {
|
||||
state.pendingLayoutRecreate = false;
|
||||
recreateVirtualScroll('recipes');
|
||||
}
|
||||
}
|
||||
|
||||
renderDuplicateGroups() {
|
||||
|
||||
@@ -1017,6 +1017,12 @@ export class SettingsManager {
|
||||
displayDensitySelect.value = state.global.settings.display_density || 'default';
|
||||
}
|
||||
|
||||
// Set recipes layout setting
|
||||
const recipesLayoutSelect = document.getElementById('recipesLayout');
|
||||
if (recipesLayoutSelect) {
|
||||
recipesLayoutSelect.value = state.global.settings.recipes_layout || 'grid';
|
||||
}
|
||||
|
||||
// Set card info display setting
|
||||
const cardInfoDisplaySelect = document.getElementById('cardInfoDisplay');
|
||||
if (cardInfoDisplaySelect) {
|
||||
@@ -2288,6 +2294,13 @@ export class SettingsManager {
|
||||
// Apply frontend settings immediately
|
||||
this.applyFrontendSettings();
|
||||
|
||||
// Dispatch layout change event; the scroller instance is about to be rebuilt,
|
||||
// so calculateLayout() must NOT run on the old instance here
|
||||
if (settingKey === 'recipes_layout') {
|
||||
window.dispatchEvent(new CustomEvent('lm:recipes-layout-changed'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Recalculate layout when display density changes
|
||||
if (settingKey === 'display_density' && state.virtualScroller) {
|
||||
state.virtualScroller.calculateLayout();
|
||||
|
||||
@@ -7,7 +7,7 @@ import { state, getCurrentPageState } from './state/index.js';
|
||||
import { getStorageItem, setStorageItem, getSessionItem, removeSessionItem } from './utils/storageHelpers.js';
|
||||
import { RecipeContextMenu } from './components/ContextMenu/index.js';
|
||||
import { DuplicatesManager } from './components/DuplicatesManager.js';
|
||||
import { refreshVirtualScroll } from './utils/infiniteScroll.js';
|
||||
import { refreshVirtualScroll, recreateVirtualScroll } from './utils/infiniteScroll.js';
|
||||
import { refreshRecipes, RecipeSidebarApiClient } from './api/recipeApi.js';
|
||||
import { sidebarManager } from './components/SidebarManager.js';
|
||||
import { initSortDropdown } from './components/controls/SortDropdown.js';
|
||||
@@ -272,6 +272,20 @@ class RecipeManager {
|
||||
});
|
||||
}
|
||||
|
||||
// Rebuild the scroller on layout switch; in duplicates mode defer until
|
||||
// exitDuplicateMode re-enables the scroller (direct recreation would dispose
|
||||
// the old instance while initializeVirtualScroll skips duplicates mode)
|
||||
window.addEventListener('lm:recipes-layout-changed', () => {
|
||||
const pageState = getCurrentPageState();
|
||||
if (pageState.duplicatesMode) {
|
||||
state.pendingLayoutRecreate = true;
|
||||
return;
|
||||
}
|
||||
if (typeof recreateVirtualScroll === 'function') {
|
||||
recreateVirtualScroll('recipes');
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize dropdown functionality for refresh button
|
||||
this.initDropdowns();
|
||||
}
|
||||
|
||||
@@ -501,3 +501,33 @@ describe('SettingsManager library controls', () => {
|
||||
expect(document.getElementById('exampleImagesUriTemplateSetting').style.display).toBe('none');
|
||||
});
|
||||
});
|
||||
|
||||
describe('SettingsManager recipes layout switch', () => {
|
||||
it('dispatches lm:recipes-layout-changed without recalculating the old scroller', async () => {
|
||||
const manager = createManager();
|
||||
const select = document.createElement('select');
|
||||
select.id = 'recipesLayout';
|
||||
const option = document.createElement('option');
|
||||
option.value = 'masonry';
|
||||
select.appendChild(option);
|
||||
select.value = 'masonry';
|
||||
document.body.appendChild(select);
|
||||
|
||||
const calculateLayout = vi.fn();
|
||||
state.virtualScroller = { calculateLayout };
|
||||
|
||||
const dispatchSpy = vi.spyOn(window, 'dispatchEvent');
|
||||
|
||||
await manager.saveSelectSetting('recipesLayout', 'recipes_layout');
|
||||
|
||||
const layoutEvent = dispatchSpy.mock.calls
|
||||
.map(([event]) => event)
|
||||
.find(event => event.type === 'lm:recipes-layout-changed');
|
||||
expect(layoutEvent).toBeInstanceOf(CustomEvent);
|
||||
expect(calculateLayout).not.toHaveBeenCalled();
|
||||
expect(showToast).not.toHaveBeenCalled();
|
||||
|
||||
dispatchSpy.mockRestore();
|
||||
delete state.virtualScroller;
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user