checkpoint

This commit is contained in:
Will Miao
2025-03-17 19:58:17 +08:00
parent 1bfe12a288
commit 710857dd41
12 changed files with 470 additions and 407 deletions

View File

@@ -1,16 +0,0 @@
import { toggleTheme, initTheme } from './utils/uiHelpers.js';
import { modalManager } from './managers/ModalManager.js';
import { updateService } from './managers/UpdateService.js';
import { SettingsManager } from './managers/SettingsManager.js';
// Export common functions
export function initializeCommonComponents() {
modalManager.initialize();
updateService.initialize();
initTheme();
// Initialize common controls
window.toggleTheme = toggleTheme;
window.modalManager = modalManager;
window.settingsManager = new SettingsManager();
}

View File

@@ -1,4 +1,5 @@
import { updateService } from '../managers/UpdateService.js';
import { toggleTheme } from '../utils/uiHelpers.js';
/**
* Header.js - Manages the application header behavior across different pages

View File

@@ -1,5 +1,6 @@
import { showToast } from '../utils/uiHelpers.js';
import { state } from '../state/index.js';
import { modalManager } from '../managers/ModalManager.js';
import { NSFW_LEVELS } from '../utils/constants.js';
export function showLoraModal(lora) {

64
static/js/core.js Normal file
View File

@@ -0,0 +1,64 @@
// Core application functionality
import { state, initSettings } from './state/index.js';
import { LoadingManager } from './managers/LoadingManager.js';
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 } from './utils/uiHelpers.js';
// Core application class
export class AppCore {
constructor() {
this.initialized = false;
}
// Initialize core functionality
async initialize() {
if (this.initialized) return;
// Initialize settings
initSettings();
// Initialize managers
state.loadingManager = new LoadingManager();
modalManager.initialize();
updateService.initialize();
window.modalManager = modalManager;
window.settingsManager = new SettingsManager();
// Initialize UI components
window.headerManager = new HeaderManager();
initTheme();
initBackToTop();
// Set up event listeners
window.addEventListener('resize', updatePanelPositions);
// Initial positioning
updatePanelPositions();
// Mark as initialized
this.initialized = true;
// Return the core instance for chaining
return this;
}
// Get the current page type
getPageType() {
const body = document.body;
return body.dataset.page || 'unknown';
}
// Show toast messages
showToast(message, type = 'info') {
showToast(message, type);
}
}
// Create and export a singleton instance
export const appCore = new AppCore();
// Export common utilities for global use
export { showToast, modalManager, state };

107
static/js/loras.js Normal file
View File

@@ -0,0 +1,107 @@
import { appCore, state } from './core.js';
import { showLoraModal, toggleShowcase, scrollToTop } from './components/LoraModal.js';
import { loadMoreLoras, fetchCivitai, deleteModel, replacePreview, resetAndReload, refreshLoras } from './api/loraApi.js';
import {
lazyLoadImages,
restoreFolderFilter,
toggleFolder,
copyTriggerWord,
openCivitai,
toggleFolderTags,
initFolderTagsVisibility,
updatePanelPositions
} from './utils/uiHelpers.js';
import { initializeInfiniteScroll } from './utils/infiniteScroll.js';
import { showDeleteModal, confirmDelete, closeDeleteModal } from './utils/modalUtils.js';
import { DownloadManager } from './managers/DownloadManager.js';
import { toggleApiKeyVisibility } from './managers/SettingsManager.js';
import { LoraContextMenu } from './components/ContextMenu.js';
import { moveManager } from './managers/MoveManager.js';
import { createLoraCard, updateCardsForBulkMode } from './components/LoraCard.js';
import { bulkManager } from './managers/BulkManager.js';
// Initialize the LoRA page
class LoraPageManager {
constructor() {
// Add bulk mode to state
state.bulkMode = false;
state.selectedLoras = new Set();
// Initialize managers
this.downloadManager = new DownloadManager();
// Expose necessary functions to the page
this._exposeGlobalFunctions();
}
_exposeGlobalFunctions() {
// Only expose what's needed for the page
window.loadMoreLoras = loadMoreLoras;
window.fetchCivitai = fetchCivitai;
window.deleteModel = deleteModel;
window.replacePreview = replacePreview;
window.toggleFolder = toggleFolder;
window.copyTriggerWord = copyTriggerWord;
window.showLoraModal = showLoraModal;
window.confirmDelete = confirmDelete;
window.closeDeleteModal = closeDeleteModal;
window.refreshLoras = refreshLoras;
window.openCivitai = openCivitai;
window.toggleFolderTags = toggleFolderTags;
window.toggleApiKeyVisibility = toggleApiKeyVisibility;
window.downloadManager = this.downloadManager;
window.moveManager = moveManager;
window.toggleShowcase = toggleShowcase;
window.scrollToTop = scrollToTop;
// Bulk operations
window.toggleBulkMode = () => bulkManager.toggleBulkMode();
window.clearSelection = () => bulkManager.clearSelection();
window.toggleCardSelection = (card) => bulkManager.toggleCardSelection(card);
window.copyAllLorasSyntax = () => bulkManager.copyAllLorasSyntax();
window.updateSelectedCount = () => bulkManager.updateSelectedCount();
window.bulkManager = bulkManager;
}
async initialize() {
// Initialize page-specific components
initializeInfiniteScroll();
initializeEventListeners();
lazyLoadImages();
restoreFolderFilter();
initFolderTagsVisibility();
new LoraContextMenu();
// Initialize cards for current bulk mode state (should be false initially)
updateCardsForBulkMode(state.bulkMode);
// Initialize the bulk manager
bulkManager.initialize();
}
}
// Initialize event listeners
function initializeEventListeners() {
const sortSelect = document.getElementById('sortSelect');
if (sortSelect) {
sortSelect.value = state.sortBy;
sortSelect.addEventListener('change', async (e) => {
state.sortBy = e.target.value;
await resetAndReload();
});
}
document.querySelectorAll('.folder-tags .tag').forEach(tag => {
tag.addEventListener('click', toggleFolder);
});
}
// Initialize everything when DOM is ready
document.addEventListener('DOMContentLoaded', async () => {
// Initialize core application
await appCore.initialize();
// Initialize page-specific functionality
const loraPage = new LoraPageManager();
await loraPage.initialize();
});

View File

@@ -1,125 +0,0 @@
import { debounce } from './utils/debounce.js';
import { LoadingManager } from './managers/LoadingManager.js';
import { modalManager } from './managers/ModalManager.js';
import { updateService } from './managers/UpdateService.js';
import { state, initSettings } from './state/index.js';
import { initializeCommonComponents } from './common.js';
import { showLoraModal } from './components/LoraModal.js';
import { toggleShowcase, scrollToTop } from './components/LoraModal.js';
import { loadMoreLoras, fetchCivitai, deleteModel, replacePreview, resetAndReload, refreshLoras } from './api/loraApi.js';
import {
showToast,
lazyLoadImages,
restoreFolderFilter,
initTheme,
toggleTheme,
toggleFolder,
copyTriggerWord,
openCivitai,
toggleFolderTags,
initFolderTagsVisibility,
initBackToTop,
updatePanelPositions
} from './utils/uiHelpers.js';
import { initializeInfiniteScroll } from './utils/infiniteScroll.js';
import { showDeleteModal, confirmDelete, closeDeleteModal } from './utils/modalUtils.js';
import { DownloadManager } from './managers/DownloadManager.js';
import { SettingsManager, toggleApiKeyVisibility } from './managers/SettingsManager.js';
import { LoraContextMenu } from './components/ContextMenu.js';
import { moveManager } from './managers/MoveManager.js';
import { createLoraCard, updateCardsForBulkMode } from './components/LoraCard.js';
import { bulkManager } from './managers/BulkManager.js';
import { HeaderManager } from './components/Header.js';
// Add bulk mode to state
state.bulkMode = false;
state.selectedLoras = new Set();
// Export functions to global window object
window.loadMoreLoras = loadMoreLoras;
window.fetchCivitai = fetchCivitai;
window.deleteModel = deleteModel;
window.replacePreview = replacePreview;
window.toggleTheme = toggleTheme;
window.toggleFolder = toggleFolder;
window.copyTriggerWord = copyTriggerWord;
window.showLoraModal = showLoraModal;
window.modalManager = modalManager;
window.state = state;
window.confirmDelete = confirmDelete;
window.closeDeleteModal = closeDeleteModal;
window.refreshLoras = refreshLoras;
window.openCivitai = openCivitai;
window.showToast = showToast
window.toggleFolderTags = toggleFolderTags;
window.settingsManager = new SettingsManager();
window.toggleApiKeyVisibility = toggleApiKeyVisibility;
window.moveManager = moveManager;
window.toggleShowcase = toggleShowcase;
window.scrollToTop = scrollToTop;
window.updatePanelPositions = updatePanelPositions;
// Export bulk manager methods to window
window.toggleBulkMode = () => bulkManager.toggleBulkMode();
window.clearSelection = () => bulkManager.clearSelection();
window.toggleCardSelection = (card) => bulkManager.toggleCardSelection(card);
window.copyAllLorasSyntax = () => bulkManager.copyAllLorasSyntax();
window.updateSelectedCount = () => bulkManager.updateSelectedCount();
window.bulkManager = bulkManager;
// Initialize everything when DOM is ready
document.addEventListener('DOMContentLoaded', async () => {
// Ensure settings are initialized
initSettings();
initializeCommonComponents();
window.headerManager = new HeaderManager();
state.loadingManager = new LoadingManager();
modalManager.initialize(); // Initialize modalManager after DOM is loaded
updateService.initialize(); // Initialize updateService after modalManager
window.downloadManager = new DownloadManager(); // Move this after modalManager initialization
// Initialize state filters from filterManager if available
if (window.filterManager && window.filterManager.filters) {
state.filters = { ...window.filterManager.filters };
}
initializeInfiniteScroll();
initializeEventListeners();
lazyLoadImages();
restoreFolderFilter();
initTheme();
initFolderTagsVisibility();
initBackToTop();
new LoraContextMenu();
// Initialize cards for current bulk mode state (should be false initially)
updateCardsForBulkMode(state.bulkMode);
// Initialize the bulk manager
bulkManager.initialize();
// Initial positioning
updatePanelPositions();
// Update positions on window resize
window.addEventListener('resize', updatePanelPositions);
// Set the current page for proper context
document.body.dataset.page = 'loras';
});
// Initialize event listeners
function initializeEventListeners() {
const sortSelect = document.getElementById('sortSelect');
if (sortSelect) {
sortSelect.value = state.sortBy;
sortSelect.addEventListener('change', async (e) => {
state.sortBy = e.target.value;
await resetAndReload();
});
}
document.querySelectorAll('.folder-tags .tag').forEach(tag => {
tag.addEventListener('click', toggleFolder);
});
}

View File

@@ -1,4 +1,5 @@
import { showToast } from '../utils/uiHelpers.js';
import { state } from '../state/index.js';
import { resetAndReload } from '../api/loraApi.js';
import { modalManager } from './ModalManager.js';

View File

@@ -1,11 +1,8 @@
// Recipe manager module
import { showToast } from './utils/uiHelpers.js';
import { state } from './state/index.js';
import { initializeCommonComponents } from './common.js';
import { appCore } from './core.js';
import { ImportManager } from './managers/ImportManager.js';
import { RecipeCard } from './components/RecipeCard.js';
import { RecipeModal } from './components/RecipeModal.js';
import { HeaderManager } from './components/Header.js';
class RecipeManager {
constructor() {
@@ -19,19 +16,24 @@ class RecipeManager {
// Initialize RecipeModal
this.recipeModal = new RecipeModal();
this.init();
}
init() {
async initialize() {
// Initialize event listeners
this.initEventListeners();
// Load initial set of recipes
this.loadRecipes();
// Set the current page for proper context
document.body.dataset.page = 'recipes';
await this.loadRecipes();
// Expose necessary functions to the page
this._exposeGlobalFunctions();
}
_exposeGlobalFunctions() {
// Only expose what's needed for the page
window.recipeManager = this;
window.importRecipes = () => this.importRecipes();
window.importManager = this.importManager;
}
initEventListeners() {
@@ -103,7 +105,7 @@ class RecipeManager {
} catch (error) {
console.error('Error loading recipes:', error);
showToast('Failed to load recipes', 'error');
appCore.showToast('Failed to load recipes', 'error');
} finally {
// Hide loading indicator
document.body.classList.remove('loading');
@@ -146,18 +148,13 @@ class RecipeManager {
}
// Initialize components
document.addEventListener('DOMContentLoaded', () => {
initializeCommonComponents();
window.headerManager = new HeaderManager();
window.recipeManager = new RecipeManager();
document.addEventListener('DOMContentLoaded', async () => {
// Initialize core application
await appCore.initialize();
// Make importRecipes function available globally
window.importRecipes = () => {
window.recipeManager.importRecipes();
};
// Expose ImportManager instance globally for the import modal event handlers
window.importManager = window.recipeManager.importManager;
// Initialize recipe manager
const recipeManager = new RecipeManager();
await recipeManager.initialize();
});
// Export for use in other modules

53
static/js/utils/routes.js Normal file
View File

@@ -0,0 +1,53 @@
// API routes configuration
export const apiRoutes = {
// LoRA routes
loras: {
list: '/api/loras',
detail: (id) => `/api/loras/${id}`,
delete: (id) => `/api/loras/${id}`,
update: (id) => `/api/loras/${id}`,
civitai: (id) => `/api/loras/${id}/civitai`,
download: '/api/download-lora',
move: '/api/move-lora',
scan: '/api/scan-loras'
},
// Recipe routes
recipes: {
list: '/api/recipes',
detail: (id) => `/api/recipes/${id}`,
delete: (id) => `/api/recipes/${id}`,
update: (id) => `/api/recipes/${id}`,
analyze: '/api/analyze-recipe-image',
save: '/api/save-recipe'
},
// Checkpoint routes
checkpoints: {
list: '/api/checkpoints',
detail: (id) => `/api/checkpoints/${id}`,
delete: (id) => `/api/checkpoints/${id}`,
update: (id) => `/api/checkpoints/${id}`
},
// WebSocket routes
ws: {
fetchProgress: (protocol) => `${protocol}://${window.location.host}/ws/fetch-progress`
}
};
// Page routes
export const pageRoutes = {
loras: '/loras',
recipes: '/loras/recipes',
checkpoints: '/checkpoints'
};
// Helper function to get current page type
export function getCurrentPageType() {
const path = window.location.pathname;
if (path.includes('/loras/recipes')) return 'recipes';
if (path.includes('/checkpoints')) return 'checkpoints';
if (path.includes('/loras')) return 'loras';
return 'unknown';
}