(field, value, options = {})
| 16967 | |
| 16968 | // Add implementation of autoSaveMultipleModels function |
| 16969 | async function autoSaveMultipleModels(field, value, options = {}) { |
| 16970 | try { |
| 16971 | // No models selected |
| 16972 | if (selectedModels.size === 0) { |
| 16973 | console.warn('No models selected for autoSaveMultipleModels'); |
| 16974 | return false; // Indicate failure/no-op |
| 16975 | } |
| 16976 | |
| 16977 | // Handle designer field default value (will be reapplied next) |
| 16978 | if (field === 'designer' && !value) { |
| 16979 | value = 'Unknown'; |
| 16980 | } |
| 16981 | |
| 16982 | // Create a copy of selectedModels to avoid issues if the set changes during iteration |
| 16983 | const modelsToUpdate = Array.from(selectedModels); |
| 16984 | console.log(`autoSaveMultipleModels: Updating ${modelsToUpdate.length} models for field ${field}`); |
| 16985 | |
| 16986 | // Load all models in parallel for better performance |
| 16987 | const modelLoadPromises = modelsToUpdate.map(async (filePath, index) => { |
| 16988 | try { |
| 16989 | console.log(`[${index}] Loading model: ${filePath}`); |
| 16990 | const model = await window.electron.getModel(filePath); |
| 16991 | if (model) { |
| 16992 | console.log(`[${index}] Successfully loaded model: ${filePath}`); |
| 16993 | return { filePath, model }; |
| 16994 | } else { |
| 16995 | console.warn(`[${index}] Could not find model for ${filePath} during autoSaveMultipleModels`); |
| 16996 | return null; |
| 16997 | } |
| 16998 | } catch (error) { |
| 16999 | console.error(`[${index}] Error loading model ${filePath} in autoSaveMultipleModels:`, error); |
| 17000 | return null; |
| 17001 | } |
| 17002 | }); |
| 17003 | |
| 17004 | // Wait for all models to load in parallel |
| 17005 | const loadedModels = await Promise.all(modelLoadPromises); |
| 17006 | console.log(`Loaded ${loadedModels.length} models, ${loadedModels.filter(r => r !== null).length} successful`); |
| 17007 | |
| 17008 | // Filter out null results and prepare updates |
| 17009 | const modelUpdates = []; |
| 17010 | for (let i = 0; i < loadedModels.length; i++) { |
| 17011 | const result = loadedModels[i]; |
| 17012 | if (result) { |
| 17013 | const { filePath, model } = result; |
| 17014 | console.log(`[${i}] Processing model update for: ${filePath}`); |
| 17015 | // Special handling for tags - MERGE or REPLACE based on options |
| 17016 | if (field === 'tags') { |
| 17017 | const newTags = Array.isArray(value) ? value : []; |
| 17018 | if (options.replaceTags) { |
| 17019 | // Replace tags completely (used when removing tags) |
| 17020 | model.tags = newTags.sort(); |
| 17021 | console.log(`[${i}] Replacing tags with: ${newTags.join(', ')}`); |
| 17022 | } else { |
| 17023 | // Merge tags (used when adding tags) |
| 17024 | const existingTags = Array.isArray(model.tags) ? model.tags : []; |
| 17025 | // Combine, filter out duplicates, and sort |
| 17026 | const allTags = [...new Set([...existingTags, ...newTags])].sort(); |
no test coverage detected