mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
Refactor panel position management and enhance recipe card handling
- Removed redundant updatePanelPositions calls from various components and centralized the logic in the uiHelpers.js for better maintainability. - Introduced appendRecipeCards function in RecipeManager to streamline the addition of recipe cards from search results. - Cleaned up unused code related to search input handling and recipe loading, improving overall code clarity and performance. - Updated HeaderManager and SearchManager to utilize the new updatePanelPositions function, ensuring consistent panel positioning across the application.
This commit is contained in:
@@ -101,53 +101,4 @@ export class HeaderManager {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to update panel positions (can be called from window resize handlers)
|
||||
updatePanelPositions() {
|
||||
if (this.searchManager && typeof this.searchManager.updatePanelPositions === 'function') {
|
||||
this.searchManager.updatePanelPositions();
|
||||
} else {
|
||||
const searchOptionsPanel = document.getElementById('searchOptionsPanel');
|
||||
const filterPanel = document.getElementById('filterPanel');
|
||||
|
||||
if (!searchOptionsPanel && !filterPanel) return;
|
||||
|
||||
// Get the header element
|
||||
const header = document.querySelector('.app-header');
|
||||
if (!header) return;
|
||||
|
||||
// Calculate the position based on the bottom of the header
|
||||
const headerRect = header.getBoundingClientRect();
|
||||
const topPosition = headerRect.bottom + 5; // Add 5px padding
|
||||
|
||||
// Set the positions
|
||||
if (searchOptionsPanel) {
|
||||
searchOptionsPanel.style.top = `${topPosition}px`;
|
||||
}
|
||||
|
||||
if (filterPanel) {
|
||||
filterPanel.style.top = `${topPosition}px`;
|
||||
}
|
||||
|
||||
// Adjust panel horizontal position based on the search container
|
||||
const searchContainer = document.querySelector('.header-search');
|
||||
if (searchContainer) {
|
||||
const searchRect = searchContainer.getBoundingClientRect();
|
||||
|
||||
// Position the search options panel aligned with the search container
|
||||
if (searchOptionsPanel) {
|
||||
searchOptionsPanel.style.right = `${window.innerWidth - searchRect.right}px`;
|
||||
}
|
||||
|
||||
// Position the filter panel aligned with the filter button
|
||||
if (filterPanel) {
|
||||
const filterButton = document.getElementById('filterButton');
|
||||
if (filterButton) {
|
||||
const filterRect = filterButton.getBoundingClientRect();
|
||||
filterPanel.style.right = `${window.innerWidth - filterRect.right}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { modalManager } from './managers/ModalManager.js';
|
||||
import { updateService } from './managers/UpdateService.js';
|
||||
import { HeaderManager } from './components/Header.js';
|
||||
import { SettingsManager } from './managers/SettingsManager.js';
|
||||
import { showToast, initTheme, initBackToTop, updatePanelPositions, lazyLoadImages } from './utils/uiHelpers.js';
|
||||
import { showToast, initTheme, initBackToTop, lazyLoadImages } from './utils/uiHelpers.js';
|
||||
import { initializeInfiniteScroll } from './utils/infiniteScroll.js';
|
||||
|
||||
// Core application class
|
||||
@@ -30,12 +30,6 @@ export class AppCore {
|
||||
initTheme();
|
||||
initBackToTop();
|
||||
|
||||
// Set up event listeners
|
||||
window.addEventListener('resize', updatePanelPositions);
|
||||
|
||||
// Initial positioning
|
||||
updatePanelPositions();
|
||||
|
||||
// Mark as initialized
|
||||
this.initialized = true;
|
||||
|
||||
@@ -66,9 +60,6 @@ export class AppCore {
|
||||
initializeInfiniteScroll(pageType);
|
||||
}
|
||||
|
||||
// Update panel positions
|
||||
updatePanelPositions();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BASE_MODELS, BASE_MODEL_CLASSES } from '../utils/constants.js';
|
||||
import { state, getCurrentPageState } from '../state/index.js';
|
||||
import { showToast } from '../utils/uiHelpers.js';
|
||||
import { showToast, updatePanelPositions } from '../utils/uiHelpers.js';
|
||||
import { resetAndReload } from '../api/loraApi.js';
|
||||
|
||||
export class FilterManager {
|
||||
@@ -155,11 +155,7 @@ export class FilterManager {
|
||||
|
||||
if (isHidden) {
|
||||
// Update panel positions before showing
|
||||
if (window.searchManager && typeof window.searchManager.updatePanelPositions === 'function') {
|
||||
window.searchManager.updatePanelPositions();
|
||||
} else if (typeof updatePanelPositions === 'function') {
|
||||
updatePanelPositions();
|
||||
}
|
||||
updatePanelPositions();
|
||||
|
||||
this.filterPanel.classList.remove('hidden');
|
||||
this.filterButton.classList.add('active');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { showToast } from '../utils/uiHelpers.js';
|
||||
import { showToast, updatePanelPositions } from '../utils/uiHelpers.js';
|
||||
|
||||
export class RecipeFilterManager {
|
||||
constructor() {
|
||||
@@ -165,11 +165,7 @@ export class RecipeFilterManager {
|
||||
|
||||
if (isHidden) {
|
||||
// Update panel positions before showing
|
||||
if (window.searchManager && typeof window.searchManager.updatePanelPositions === 'function') {
|
||||
window.searchManager.updatePanelPositions();
|
||||
} else if (typeof updatePanelPositions === 'function') {
|
||||
updatePanelPositions();
|
||||
}
|
||||
updatePanelPositions();
|
||||
|
||||
this.filterPanel.classList.remove('hidden');
|
||||
this.filterButton.classList.add('active');
|
||||
|
||||
@@ -33,10 +33,7 @@ export class RecipeSearchManager extends SearchManager {
|
||||
const grid = document.getElementById('recipeGrid');
|
||||
|
||||
if (!searchTerm) {
|
||||
if (state) {
|
||||
state.pages.recipes.currentPage = 1;
|
||||
}
|
||||
this.resetAndReloadRecipes();
|
||||
window.recipeManager.loadRecipes();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -112,34 +109,12 @@ export class RecipeSearchManager extends SearchManager {
|
||||
}
|
||||
}
|
||||
|
||||
resetAndReloadRecipes() {
|
||||
if (window.recipeManager && typeof window.recipeManager.loadRecipes === 'function') {
|
||||
window.recipeManager.loadRecipes();
|
||||
} else {
|
||||
// Fallback to reloading the page
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
appendRecipeCards(recipes) {
|
||||
// This function would be implemented in the recipes page
|
||||
// Similar to appendLoraCards for loras
|
||||
const grid = document.getElementById('recipeGrid');
|
||||
if (!grid) return;
|
||||
|
||||
if (typeof window.appendRecipeCards === 'function') {
|
||||
window.appendRecipeCards(recipes);
|
||||
} else {
|
||||
// Fallback implementation
|
||||
recipes.forEach(recipe => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'recipe-card';
|
||||
card.innerHTML = `
|
||||
<h3>${recipe.name}</h3>
|
||||
<p>${recipe.description || 'No description'}</p>
|
||||
`;
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
// Create data object in the format expected by the RecipeManager
|
||||
const data = { items: recipes, has_more: false };
|
||||
window.recipeManager.updateRecipesGrid(data, false);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { updatePanelPositions } from "../utils/uiHelpers.js";
|
||||
/**
|
||||
* SearchManager - Handles search functionality across different pages
|
||||
* Each page can extend or customize this base functionality
|
||||
@@ -27,11 +28,10 @@ export class SearchManager {
|
||||
this.initEventListeners();
|
||||
this.loadSearchPreferences();
|
||||
|
||||
// Initialize panel positions
|
||||
this.updatePanelPositions();
|
||||
updatePanelPositions();
|
||||
|
||||
// Add resize listener
|
||||
window.addEventListener('resize', this.updatePanelPositions.bind(this));
|
||||
window.addEventListener('resize', updatePanelPositions);
|
||||
}
|
||||
|
||||
initEventListeners() {
|
||||
@@ -161,7 +161,7 @@ export class SearchManager {
|
||||
const isHidden = this.searchOptionsPanel.classList.contains('hidden');
|
||||
if (isHidden) {
|
||||
// Update position before showing
|
||||
this.updatePanelPositions();
|
||||
updatePanelPositions();
|
||||
this.searchOptionsPanel.classList.remove('hidden');
|
||||
this.searchOptionsToggle.classList.add('active');
|
||||
|
||||
@@ -267,56 +267,6 @@ export class SearchManager {
|
||||
return options;
|
||||
}
|
||||
|
||||
updatePanelPositions() {
|
||||
const searchOptionsPanel = document.getElementById('searchOptionsPanel');
|
||||
const filterPanel = document.getElementById('filterPanel');
|
||||
|
||||
if (!searchOptionsPanel && !filterPanel) return;
|
||||
|
||||
// Get the header element
|
||||
const header = document.querySelector('.app-header');
|
||||
if (!header) return;
|
||||
|
||||
// Calculate the position based on the bottom of the header
|
||||
const headerRect = header.getBoundingClientRect();
|
||||
const topPosition = headerRect.bottom + 5; // Add 5px padding
|
||||
|
||||
// Set the positions
|
||||
if (searchOptionsPanel) {
|
||||
searchOptionsPanel.style.top = `${topPosition}px`;
|
||||
|
||||
// Make sure the panel is visible when positioned
|
||||
if (!searchOptionsPanel.classList.contains('hidden') &&
|
||||
window.getComputedStyle(searchOptionsPanel).display === 'none') {
|
||||
searchOptionsPanel.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
if (filterPanel) {
|
||||
filterPanel.style.top = `${topPosition}px`;
|
||||
}
|
||||
|
||||
// Adjust panel horizontal position based on the search container
|
||||
const searchContainer = document.querySelector('.header-search');
|
||||
if (searchContainer) {
|
||||
const searchRect = searchContainer.getBoundingClientRect();
|
||||
|
||||
// Position the search options panel aligned with the search container
|
||||
if (searchOptionsPanel) {
|
||||
searchOptionsPanel.style.right = `${window.innerWidth - searchRect.right}px`;
|
||||
}
|
||||
|
||||
// Position the filter panel aligned with the filter button
|
||||
if (filterPanel) {
|
||||
const filterButton = document.getElementById('filterButton');
|
||||
if (filterButton) {
|
||||
const filterRect = filterButton.getBoundingClientRect();
|
||||
filterPanel.style.right = `${window.innerWidth - filterRect.right}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
performSearch() {
|
||||
const query = this.searchInput.value.trim();
|
||||
const options = this.getActiveSearchOptions();
|
||||
|
||||
@@ -59,6 +59,12 @@ class RecipeManager {
|
||||
window.importRecipes = () => this.importRecipes();
|
||||
window.importManager = this.importManager;
|
||||
window.loadMoreRecipes = () => this.loadMoreRecipes();
|
||||
|
||||
// Add appendRecipeCards function for the search manager to use
|
||||
window.appendRecipeCards = (recipes) => {
|
||||
const data = { items: recipes, has_more: false };
|
||||
this.updateRecipesGrid(data, false);
|
||||
};
|
||||
}
|
||||
|
||||
initEventListeners() {
|
||||
@@ -70,28 +76,6 @@ class RecipeManager {
|
||||
this.loadRecipes();
|
||||
});
|
||||
}
|
||||
|
||||
// Search input
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
if (searchInput) {
|
||||
let debounceTimeout;
|
||||
searchInput.addEventListener('input', () => {
|
||||
clearTimeout(debounceTimeout);
|
||||
debounceTimeout = setTimeout(() => {
|
||||
this.pageState.filters.search = searchInput.value;
|
||||
this.loadRecipes();
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
|
||||
// Import button
|
||||
const importButton = document.querySelector('button[onclick="importRecipes()"]');
|
||||
if (importButton) {
|
||||
importButton.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
this.importManager.showImportModal();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async loadRecipes(resetPage = true) {
|
||||
|
||||
@@ -106,20 +106,45 @@ export function updatePanelPositions() {
|
||||
const searchOptionsPanel = document.getElementById('searchOptionsPanel');
|
||||
const filterPanel = document.getElementById('filterPanel');
|
||||
|
||||
if (!searchOptionsPanel || !filterPanel) return;
|
||||
if (!searchOptionsPanel && !filterPanel) return;
|
||||
|
||||
// Get the controls container
|
||||
const controls = document.querySelector('.controls');
|
||||
if (!controls) return;
|
||||
// Get the header element
|
||||
const header = document.querySelector('.app-header');
|
||||
if (!header) return;
|
||||
|
||||
// Calculate the position based on the bottom of the controls container
|
||||
const controlsRect = controls.getBoundingClientRect();
|
||||
const topPosition = controlsRect.bottom + 10; // Add 10px padding
|
||||
// Calculate the position based on the bottom of the header
|
||||
const headerRect = header.getBoundingClientRect();
|
||||
const topPosition = headerRect.bottom + 5; // Add 5px padding
|
||||
|
||||
// Set the positions
|
||||
searchOptionsPanel.style.top = `${topPosition}px`;
|
||||
filterPanel.style.top = `${topPosition}px`;
|
||||
}
|
||||
if (searchOptionsPanel) {
|
||||
searchOptionsPanel.style.top = `${topPosition}px`;
|
||||
}
|
||||
|
||||
if (filterPanel) {
|
||||
filterPanel.style.top = `${topPosition}px`;
|
||||
}
|
||||
|
||||
// Adjust panel horizontal position based on the search container
|
||||
const searchContainer = document.querySelector('.header-search');
|
||||
if (searchContainer) {
|
||||
const searchRect = searchContainer.getBoundingClientRect();
|
||||
|
||||
// Position the search options panel aligned with the search container
|
||||
if (searchOptionsPanel) {
|
||||
searchOptionsPanel.style.right = `${window.innerWidth - searchRect.right}px`;
|
||||
}
|
||||
|
||||
// Position the filter panel aligned with the filter button
|
||||
if (filterPanel) {
|
||||
const filterButton = document.getElementById('filterButton');
|
||||
if (filterButton) {
|
||||
const filterRect = filterButton.getBoundingClientRect();
|
||||
filterPanel.style.right = `${window.innerWidth - filterRect.right}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the toggleFolderTags function
|
||||
export function toggleFolderTags() {
|
||||
@@ -144,11 +169,7 @@ export function toggleFolderTags() {
|
||||
// Update panel positions after toggling
|
||||
// Use a small delay to ensure the DOM has updated
|
||||
setTimeout(() => {
|
||||
if (window.searchManager && typeof window.searchManager.updatePanelPositions === 'function') {
|
||||
window.searchManager.updatePanelPositions();
|
||||
} else if (typeof updatePanelPositions === 'function') {
|
||||
updatePanelPositions();
|
||||
}
|
||||
updatePanelPositions();
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,14 +76,4 @@
|
||||
|
||||
{% block main_script %}
|
||||
<script type="module" src="/loras_static/js/recipes.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block additional_scripts %}
|
||||
<script>
|
||||
// Refresh recipes
|
||||
function refreshRecipes() {
|
||||
// Will be implemented in recipes.js
|
||||
window.location.reload();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user