mirror of
https://github.com/yusufipk/imagen-openrouter.git
synced 2026-09-11 10:36:07 +00:00
feat: enhance state management for image generation settings and restore functionality
This commit is contained in:
+61
-38
@@ -90,9 +90,9 @@ const ImagenDB = {
|
|||||||
const state = {
|
const state = {
|
||||||
apiKey: localStorage.getItem('imagen_api_key') || '',
|
apiKey: localStorage.getItem('imagen_api_key') || '',
|
||||||
selectedModel: localStorage.getItem('imagen_model') || 'google/gemini-2.5-flash-image',
|
selectedModel: localStorage.getItem('imagen_model') || 'google/gemini-2.5-flash-image',
|
||||||
imageSize: '1024x1024',
|
imageSize: localStorage.getItem('imagen_size') || '1024x1024',
|
||||||
imageQuality: '1K',
|
imageQuality: localStorage.getItem('imagen_quality') || '1K',
|
||||||
aspectRatio: '1:1',
|
aspectRatio: localStorage.getItem('imagen_aspect_ratio') || '1:1',
|
||||||
imageCount: 1,
|
imageCount: 1,
|
||||||
references: [], // Dynamic array - unlimited references
|
references: [], // Dynamic array - unlimited references
|
||||||
images: [], // Will be loaded from IndexedDB
|
images: [], // Will be loaded from IndexedDB
|
||||||
@@ -251,6 +251,22 @@ async function init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore saved image quality/size
|
||||||
|
document.querySelectorAll('.btn-toggle').forEach(btn => {
|
||||||
|
btn.classList.remove('active');
|
||||||
|
if (btn.dataset.quality === state.imageQuality) {
|
||||||
|
btn.classList.add('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Restore saved aspect ratio
|
||||||
|
document.querySelectorAll('.btn-aspect').forEach(btn => {
|
||||||
|
btn.classList.remove('active');
|
||||||
|
if (btn.dataset.ratio === state.aspectRatio) {
|
||||||
|
btn.classList.add('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Load images from IndexedDB
|
// Load images from IndexedDB
|
||||||
try {
|
try {
|
||||||
state.images = await ImagenDB.getAllImages();
|
state.images = await ImagenDB.getAllImages();
|
||||||
@@ -303,6 +319,8 @@ function setupEventListeners() {
|
|||||||
btn.classList.add('active');
|
btn.classList.add('active');
|
||||||
state.imageSize = btn.dataset.size;
|
state.imageSize = btn.dataset.size;
|
||||||
state.imageQuality = btn.dataset.quality;
|
state.imageQuality = btn.dataset.quality;
|
||||||
|
localStorage.setItem('imagen_size', state.imageSize);
|
||||||
|
localStorage.setItem('imagen_quality', state.imageQuality);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -312,6 +330,7 @@ function setupEventListeners() {
|
|||||||
document.querySelectorAll('.btn-aspect').forEach(b => b.classList.remove('active'));
|
document.querySelectorAll('.btn-aspect').forEach(b => b.classList.remove('active'));
|
||||||
btn.classList.add('active');
|
btn.classList.add('active');
|
||||||
state.aspectRatio = btn.dataset.ratio;
|
state.aspectRatio = btn.dataset.ratio;
|
||||||
|
localStorage.setItem('imagen_aspect_ratio', state.aspectRatio);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -528,60 +547,59 @@ async function generateImages() {
|
|||||||
elements.generateBtn.disabled = true;
|
elements.generateBtn.disabled = true;
|
||||||
elements.loadingContainer.style.display = 'flex';
|
elements.loadingContainer.style.display = 'flex';
|
||||||
|
|
||||||
try {
|
|
||||||
const modelConfig = MODEL_CONFIGS[state.selectedModel];
|
const modelConfig = MODEL_CONFIGS[state.selectedModel];
|
||||||
const promises = [];
|
const currentReferences = state.references.length > 0 ? [...state.references] : [];
|
||||||
|
console.log('Generating with references:', currentReferences.length, currentReferences);
|
||||||
for (let i = 0; i < state.imageCount; i++) {
|
|
||||||
promises.push(generateSingleImage(prompt, modelConfig));
|
|
||||||
}
|
|
||||||
|
|
||||||
const results = await Promise.allSettled(promises);
|
|
||||||
|
|
||||||
let successCount = 0;
|
let successCount = 0;
|
||||||
const newImages = [];
|
let failCount = 0;
|
||||||
|
|
||||||
results.forEach((result, index) => {
|
// Generate images and display each one as it completes
|
||||||
if (result.status === 'fulfilled' && result.value) {
|
const generateAndDisplay = async (index) => {
|
||||||
|
try {
|
||||||
|
const result = await generateSingleImage(prompt, modelConfig);
|
||||||
|
if (result) {
|
||||||
const imageData = {
|
const imageData = {
|
||||||
id: Date.now() + index,
|
id: Date.now() + index,
|
||||||
url: result.value,
|
url: result,
|
||||||
prompt: prompt,
|
prompt: prompt,
|
||||||
model: state.selectedModel,
|
model: state.selectedModel,
|
||||||
modelName: modelConfig.name,
|
modelName: modelConfig.name,
|
||||||
size: state.imageSize,
|
size: state.imageSize,
|
||||||
quality: state.imageQuality,
|
quality: state.imageQuality,
|
||||||
aspectRatio: state.aspectRatio,
|
aspectRatio: state.aspectRatio,
|
||||||
references: state.references.length > 0 ? [...state.references] : [],
|
references: currentReferences,
|
||||||
createdAt: new Date().toISOString()
|
createdAt: new Date().toISOString()
|
||||||
};
|
};
|
||||||
newImages.push(imageData);
|
|
||||||
state.images.unshift(imageData);
|
state.images.unshift(imageData);
|
||||||
successCount++;
|
|
||||||
} else {
|
|
||||||
console.error('Failed to generate image:', result.reason);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (successCount > 0) {
|
|
||||||
// Render gallery immediately so user sees results
|
|
||||||
renderGallery();
|
renderGallery();
|
||||||
showToast(`${successCount} image(s) generated!`, 'success');
|
successCount++;
|
||||||
|
|
||||||
// Save to IndexedDB in background (don't block UI)
|
// Save to IndexedDB in background
|
||||||
Promise.all(newImages.map(img => ImagenDB.saveImage(img)))
|
ImagenDB.saveImage(imageData).catch(e => console.error('Failed to save to IndexedDB:', e));
|
||||||
.catch(dbError => console.error('Failed to save to IndexedDB:', dbError));
|
}
|
||||||
} else {
|
} catch (error) {
|
||||||
showToast('Failed to generate images. Check console for details.', 'error');
|
console.error('Failed to generate image:', error);
|
||||||
|
failCount++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start all generations in parallel, each will render when done
|
||||||
|
const promises = [];
|
||||||
|
for (let i = 0; i < state.imageCount; i++) {
|
||||||
|
promises.push(generateAndDisplay(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
// Wait for all to complete to update final UI state
|
||||||
console.error('Generation error:', error);
|
await Promise.allSettled(promises);
|
||||||
showToast(`Error: ${error.message}`, 'error');
|
|
||||||
} finally {
|
|
||||||
state.isGenerating = false;
|
state.isGenerating = false;
|
||||||
elements.generateBtn.disabled = false;
|
elements.generateBtn.disabled = false;
|
||||||
elements.loadingContainer.style.display = 'none';
|
elements.loadingContainer.style.display = 'none';
|
||||||
|
|
||||||
|
if (successCount > 0) {
|
||||||
|
showToast(`${successCount} image(s) generated!`, 'success');
|
||||||
|
} else {
|
||||||
|
showToast('Failed to generate images. Check console for details.', 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,11 +856,16 @@ function recreateImage() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Restore references
|
// Restore references (always update the UI, even if empty to clear previous refs)
|
||||||
|
console.log('Recreate - image references:', state.currentImage.references);
|
||||||
if (state.currentImage.references && state.currentImage.references.length > 0) {
|
if (state.currentImage.references && state.currentImage.references.length > 0) {
|
||||||
state.references = [...state.currentImage.references];
|
state.references = [...state.currentImage.references];
|
||||||
renderReferenceSlots();
|
console.log('Restored references:', state.references.length);
|
||||||
|
} else {
|
||||||
|
state.references = [];
|
||||||
|
console.log('No references to restore');
|
||||||
}
|
}
|
||||||
|
renderReferenceSlots();
|
||||||
|
|
||||||
closeModal();
|
closeModal();
|
||||||
showToast('Settings restored. Click Generate to recreate.', 'success');
|
showToast('Settings restored. Click Generate to recreate.', 'success');
|
||||||
|
|||||||
Reference in New Issue
Block a user