Files
arcum42-ComfyUI_SageUtils/js/shared/config.js
T

538 lines
14 KiB
JavaScript

/**
* Centralized Configuration for Sidebar Components
* Contains all constants, file type patterns, API endpoints, and styling configuration
*/
/**
* File type detection patterns
*/
export const FILE_TYPES = {
image: /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|tif|ico|heic|heif|avif)$/i,
rawImage: /\.(raw|cr2|nef|arw|dng|orf|pef|sr2|srw|x3f)$/i,
video: /\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv|m4v)$/i,
text: /\.(txt|md|markdown|json|js|ts|py|yaml|yml|csv|log)$/i,
markdown: /\.(md|markdown)$/i
};
/**
* API endpoints configuration
*/
export const API_ENDPOINTS = {
// Cache management
cacheHash: '/sage_utils/cache_hash',
cacheInfo: '/sage_utils/cache_info',
updateCacheInfo: '/sage_utils/update_cache_info',
pullMetadata: '/sage_utils/pull_metadata',
scanModelFolders: '/sage_utils/scan_model_folders',
// Notes management
listNotes: '/sage_utils/list_notes',
readNote: '/sage_utils/read_note',
saveNote: '/sage_utils/save_note',
deleteNote: '/sage_utils/delete_note',
// Utility endpoints
getFileSize: '/sage_utils/get_file_size',
// Gallery management
listImages: '/sage_utils/list_images',
getThumbnail: '/sage_utils/thumbnail',
getImageMetadata: '/sage_utils/image_metadata',
browseFolder: '/sage_utils/browse_folder',
copyImage: '/sage_utils/copy_image'
};
/**
* Filter options for dropdowns
*/
export const FILTER_OPTIONS = {
folderType: [
{ value: 'all', text: 'All Folders' },
{ value: 'checkpoints', text: 'Checkpoints' },
{ value: 'loras', text: 'LoRA Models' },
{ value: 'vae', text: 'VAE Models' },
{ value: 'text_encoders', text: 'Text Encoders' },
{ value: 'diffusion_models', text: 'Diffusion Models' },
// Additional folder types that might be wanted later:
// { value: 'embeddings', text: 'Embeddings' },
// { value: 'clip_vision', text: 'CLIP Vision' },
// { value: 'style_models', text: 'Style Models' },
// { value: 'controlnet', text: 'ControlNet' }
],
lastUsed: [
{ value: 'all', text: 'Any Time' },
{ value: 'today', text: 'Used Today' },
{ value: 'week', text: 'Used This Week' },
{ value: 'month', text: 'Used This Month' },
{ value: 'never', text: 'Never Used' }
],
updates: [
{ value: 'all', text: 'All Models' },
{ value: 'available', text: 'Updates Available' },
{ value: 'none', text: 'No Updates Available' }
],
sort: [
{ value: 'name', text: 'Name (A-Z)' },
{ value: 'name-desc', text: 'Name (Z-A)' },
{ value: 'lastused', text: 'Recently Used' },
{ value: 'lastused-desc', text: 'Oldest Used' },
{ value: 'size', text: 'File Size (Small)' },
{ value: 'size-desc', text: 'File Size (Large)' },
{ value: 'type', text: 'Folder Type' }
]
};
/**
* Button configurations for consistent styling and behavior
*/
export const BUTTON_CONFIGS = {
refresh: {
text: 'Refresh',
color: '#4CAF50',
icon: '🔄'
},
pull: {
text: 'Pull',
color: '#2196F3',
icon: '⬇'
},
edit: {
text: 'Edit',
color: '#FF9800',
icon: '✏️'
},
scan: {
text: 'Scan All',
color: '#9C27B0',
icon: '🔍'
},
report: {
text: 'Report',
color: '#607D8B',
icon: '📊'
},
save: {
text: 'Save',
color: '#4CAF50',
icon: '💾'
},
delete: {
text: 'Delete',
color: '#F44336',
icon: '🗑️'
},
newFile: {
text: 'New File',
color: '#2196F3',
icon: '📄'
},
gallery: {
text: 'Gallery',
color: '#9C27B0',
icon: '🖼️'
},
viewImage: {
text: 'View',
color: '#4CAF50',
icon: '👁️'
},
copyImage: {
text: 'Copy',
color: '#FF9800',
icon: '📋'
},
showMetadata: {
text: 'Details',
color: '#607D8B',
icon: '🔍'
}
};
/**
* Common CSS styles for consistent theming
*/
export const STYLES = {
colors: {
primary: '#4CAF50',
secondary: '#2196F3',
warning: '#FF9800',
error: '#F44336',
info: '#9C27B0',
muted: '#607D8B',
// Background colors
background: '#1e1e1e',
panel: '#2a2a2a',
card: '#333333',
input: '#1a1a1a',
// Text colors
text: '#ffffff',
textSecondary: '#e0e0e0',
textMuted: '#888888',
// Border colors
border: '#444444',
borderLight: '#555555'
},
spacing: {
xs: '2px',
sm: '5px',
md: '10px',
lg: '15px',
xl: '20px'
},
typography: {
fontFamily: {
body: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
mono: '"Courier New", monospace'
},
fontSize: {
xs: '10px',
sm: '11px',
md: '12px',
lg: '13px',
xl: '14px'
}
},
components: {
button: {
base: `
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-weight: bold;
transition: all 0.2s ease;
display: inline-flex;
align-items: center;
gap: 5px;
`,
small: `
padding: 4px 8px;
font-size: 11px;
`,
disabled: `
opacity: 0.5;
cursor: not-allowed;
`
},
input: {
base: `
padding: 8px;
background: #1a1a1a;
color: #fff;
border: 1px solid #555;
border-radius: 4px;
font-size: 12px;
font-family: inherit;
transition: border-color 0.2s ease;
`,
focus: `
border-color: #4CAF50;
outline: none;
`,
error: `
border-color: #F44336;
`
},
select: {
base: `
padding: 8px;
background: #333;
color: #fff;
border: 1px solid #555;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
`
},
panel: {
base: `
padding: 15px;
background: #2a2a2a;
border-radius: 6px;
border: 1px solid #444;
margin-bottom: 15px;
`,
header: `
margin: 0 0 10px 0;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
`
},
dropdown: {
container: `
position: relative;
width: 100%;
`,
button: `
width: 100%;
padding: 8px 12px;
background: #333;
color: #fff;
border: 1px solid #555;
border-radius: 4px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
transition: background-color 0.2s ease;
`,
menu: `
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #333;
border: 1px solid #555;
border-top: none;
border-radius: 0 0 4px 4px;
max-height: 300px;
overflow-y: auto;
z-index: 1000;
display: none;
`,
item: `
padding: 8px 12px;
cursor: pointer;
border-bottom: 1px solid #444;
transition: background-color 0.2s ease;
color: #fff;
font-size: 12px;
`
}
}
};
/**
* Animation and transition configurations
*/
export const ANIMATIONS = {
durations: {
fast: '0.15s',
normal: '0.2s',
slow: '0.3s'
},
easings: {
smooth: 'ease',
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
sharp: 'cubic-bezier(0.4, 0, 0.2, 1)'
}
};
/**
* Performance and caching settings
*/
export const PERFORMANCE = {
// API response caching
cache: {
ttl: 5 * 60 * 1000, // 5 minutes
maxSize: 100 // Maximum number of cached responses
},
// Debounce delays for user input
debounce: {
search: 300,
resize: 100,
scroll: 50
},
// Batch processing settings
batch: {
maxSize: 50, // Maximum items to process in one batch
delay: 2000 // Delay between API calls (milliseconds)
}
};
/**
* Error messages and user feedback
*/
export const MESSAGES = {
errors: {
generic: 'An unexpected error occurred',
network: 'Network error - please check your connection',
notFound: 'Requested resource not found',
unauthorized: 'You are not authorized to perform this action',
validation: 'Invalid input provided',
fileNotFound: 'File not found',
saveFailed: 'Failed to save file',
loadFailed: 'Failed to load data'
},
success: {
saved: 'File saved successfully',
deleted: 'File deleted successfully',
updated: 'Information updated successfully',
loaded: 'Data loaded successfully'
},
loading: {
default: 'Loading...',
files: 'Loading files...',
models: 'Loading models...',
metadata: 'Loading metadata...',
saving: 'Saving...',
deleting: 'Deleting...'
}
};
/**
* Development and debugging settings
*/
export const DEBUG = {
enabled: false, // Set to true for development
logLevel: 'info', // 'error', 'warn', 'info', 'debug'
components: {
stateManager: false,
apiCalls: false,
uiUpdates: false
}
};
/**
* Feature flags for progressive enhancement
*/
export const FEATURES = {
markdownPreview: true,
imagePreview: true,
videoPreview: true,
advancedFiltering: true,
batchOperations: true,
autoSave: true,
keyboardShortcuts: true
};
/**
* Gallery-specific configuration
*/
export const GALLERY_CONFIG = {
thumbnailSizes: {
small: { width: 120, height: 120 },
medium: { width: 200, height: 200 },
large: { width: 300, height: 300 }
},
virtualScroll: {
enabled: true,
threshold: 100, // Enable for collections > 100 images
buffer: 10 // Number of items to render outside viewport
},
cache: {
maxThumbnails: 500,
maxFullImages: 50,
ttl: 24 * 60 * 60 * 1000 // 24 hours
},
supportedImageFormats: [
'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg',
'tiff', 'tif', 'ico', 'heic', 'heif', 'avif'
],
supportedRawFormats: [
'raw', 'cr2', 'nef', 'arw', 'dng', 'orf',
'pef', 'sr2', 'srw', 'x3f'
],
defaultFolders: [
{ value: 'notes', text: '📝 Notes Folder', icon: '📝' },
{ value: 'input', text: '📥 Input Folder', icon: '📥' },
{ value: 'output', text: '📤 Output Folder', icon: '📤' }
],
sortOptions: [
{ value: 'name', text: 'Name (A-Z)' },
{ value: 'name-desc', text: 'Name (Z-A)' },
{ value: 'date', text: 'Date (Newest)' },
{ value: 'date-desc', text: 'Date (Oldest)' },
{ value: 'size', text: 'Size (Largest)' },
{ value: 'size-desc', text: 'Size (Smallest)' }
],
viewModes: [
{ value: 'grid', text: 'Grid View', icon: '⊞' },
{ value: 'list', text: 'List View', icon: '☰' }
]
};
/**
* Helper function to check if a file is a supported image format
* @param {string} filename - The filename to check
* @returns {boolean} Whether the file is a supported image
*/
export function isSupportedImage(filename) {
if (!filename) return false;
return FILE_TYPES.image.test(filename.toLowerCase()) || FILE_TYPES.rawImage.test(filename.toLowerCase());
}
/**
* Helper function to get thumbnail size configuration
* @param {string} size - Size name ('small', 'medium', 'large')
* @returns {Object} Size configuration with width and height
*/
export function getThumbnailSize(size) {
return GALLERY_CONFIG.thumbnailSizes[size] || GALLERY_CONFIG.thumbnailSizes.medium;
}
/**
* Helper function to get file type from filename
* @param {string} filename - The filename to check
* @returns {string} The file type ('image', 'rawImage', 'video', 'text', 'markdown', 'unknown')
*/
export function getFileType(filename) {
if (!filename) return 'unknown';
const lower = filename.toLowerCase();
if (FILE_TYPES.image.test(lower)) return 'image';
if (FILE_TYPES.rawImage.test(lower)) return 'rawImage';
if (FILE_TYPES.video.test(lower)) return 'video';
if (FILE_TYPES.markdown.test(lower)) return 'markdown';
if (FILE_TYPES.text.test(lower)) return 'text';
return 'unknown';
}
/**
* Helper function to check if a file type is supported for preview
* @param {string} fileType - The file type to check
* @returns {boolean} Whether the file type supports preview
*/
export function supportsPreview(fileType) {
return ['image', 'rawImage', 'video', 'markdown'].includes(fileType);
}
/**
* Helper function to get appropriate icon for file type
* @param {string} fileType - The file type
* @returns {string} Unicode icon for the file type
*/
export function getFileTypeIcon(fileType) {
const icons = {
image: '🖼️',
rawImage: '📷',
video: '🎬',
markdown: '📝',
text: '📄',
unknown: '📋'
};
return icons[fileType] || icons.unknown;
}