/** * CheckpointModal - Main entry point * * Modularized checkpoint modal component that handles checkpoint model details display */ import { showToast } from '../../utils/uiHelpers.js'; import { state } from '../../state/index.js'; import { modalManager } from '../../managers/ModalManager.js'; import { renderShowcaseContent, toggleShowcase, setupShowcaseScroll, scrollToTop } from './ShowcaseView.js'; import { setupTabSwitching, loadModelDescription } from './ModelDescription.js'; import { setupModelNameEditing, setupBaseModelEditing, setupFileNameEditing, saveModelMetadata } from './ModelMetadata.js'; import { renderCompactTags, setupTagTooltip, formatFileSize } from './utils.js'; /** * Display the checkpoint modal with the given checkpoint data * @param {Object} checkpoint - Checkpoint data object */ export function showCheckpointModal(checkpoint) { const content = ` `; modalManager.showModal('checkpointModal', content); setupEditableFields(); setupShowcaseScroll(); setupTabSwitching(); setupTagTooltip(); setupModelNameEditing(); setupBaseModelEditing(); setupFileNameEditing(); // If we have a model ID but no description, fetch it if (checkpoint.civitai?.modelId && !checkpoint.modelDescription) { loadModelDescription(checkpoint.civitai.modelId, checkpoint.file_path); } } /** * Set up editable fields in the checkpoint modal */ function setupEditableFields() { const editableFields = document.querySelectorAll('.editable-field [contenteditable]'); editableFields.forEach(field => { field.addEventListener('focus', function() { if (this.textContent === 'Add your notes here...') { this.textContent = ''; } }); field.addEventListener('blur', function() { if (this.textContent.trim() === '') { if (this.classList.contains('notes-content')) { this.textContent = 'Add your notes here...'; } } }); }); // Add keydown event listeners for notes const notesContent = document.querySelector('.notes-content'); if (notesContent) { notesContent.addEventListener('keydown', async function(e) { if (e.key === 'Enter') { if (e.shiftKey) { // Allow shift+enter for new line return; } e.preventDefault(); const filePath = document.querySelector('#checkpointModal .modal-content') .querySelector('.file-path').textContent + document.querySelector('#checkpointModal .modal-content') .querySelector('#file-name').textContent; await saveNotes(filePath); } }); } } /** * Save checkpoint notes * @param {string} filePath - Path to the checkpoint file */ async function saveNotes(filePath) { const content = document.querySelector('.notes-content').textContent; try { await saveModelMetadata(filePath, { notes: content }); // Update the corresponding checkpoint card's dataset const checkpointCard = document.querySelector(`.checkpoint-card[data-filepath="${filePath}"]`); if (checkpointCard) { checkpointCard.dataset.notes = content; } showToast('Notes saved successfully', 'success'); } catch (error) { showToast('Failed to save notes', 'error'); } } // Export the checkpoint modal API const checkpointModal = { show: showCheckpointModal, toggleShowcase, scrollToTop }; export { checkpointModal }; // Define global functions for use in HTML window.toggleShowcase = function(element) { toggleShowcase(element); }; window.scrollToTopCheckpoint = function(button) { scrollToTop(button); }; window.saveCheckpointNotes = function(filePath) { saveNotes(filePath); };