document.addEventListener('DOMContentLoaded', () => { const form = document.getElementById('generation-form'); const mediaType = document.getElementById('media-type'); const videoProviderContainer = document.getElementById('video-provider-container'); const generateBtn = document.getElementById('generate-btn'); const placeholderText = document.getElementById('placeholder-text'); const loadingState = document.getElementById('loading-state'); const contentContainer = document.getElementById('content-container'); const actionButtons = document.getElementById('action-buttons'); const downloadBtn = document.getElementById('download-btn'); const editBtn = document.getElementById('edit-btn'); const providerBadge = document.getElementById('provider-badge'); const infoOverlay = document.getElementById('info-overlay'); const statusMessage = document.getElementById('status-message'); // Editor Elements const editorModal = new bootstrap.Modal(document.getElementById('editorModal')); const editorCanvas = document.getElementById('editor-canvas'); const ctx = editorCanvas.getContext('2d'); const filterRanges = document.querySelectorAll('.filter-range'); const resetFiltersBtn = document.getElementById('reset-filters'); const saveEditedBtn = document.getElementById('save-edited-btn'); const editorLoading = document.getElementById('editor-loading'); // AI Magic Elements const aiEditPrompt = document.getElementById('ai-edit-prompt'); const applyAiMagicBtn = document.getElementById('apply-ai-magic'); const removeBgBtn = document.getElementById('remove-bg-btn'); const upscaleBtn = document.getElementById('upscale-btn'); let currentImage = null; let originalPrompt = ''; // Local storage for settings const getRapidKey = () => localStorage.getItem('rapidapi_key') || ''; const setRapidKey = (key) => localStorage.setItem('rapidapi_key', key); // Sync input with local storage const keyInput = document.getElementById('rapidapi-key-input'); if (keyInput) { keyInput.value = getRapidKey(); keyInput.addEventListener('change', (e) => setRapidKey(e.target.value)); } // Toggle video provider field mediaType.addEventListener('change', () => { if (mediaType.value === 'video') { videoProviderContainer.style.display = 'block'; } else { videoProviderContainer.style.display = 'none'; } }); form.addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(form); formData.append('rapidapi_key', getRapidKey()); originalPrompt = formData.get('prompt'); // UI State: Loading placeholderText.classList.add('d-none'); contentContainer.classList.add('d-none'); actionButtons.classList.add('d-none'); infoOverlay.classList.add('d-none'); statusMessage.classList.add('d-none'); loadingState.classList.remove('d-none'); generateBtn.disabled = true; try { const response = await fetch('api/generate.php', { method: 'POST', body: formData }); const result = await response.json(); if (result.success) { renderResult(result); } else { alert('Ошибка: ' + (result.error || 'Что-то пошло не так')); resetUI(); } } catch (error) { console.error('Generation error:', error); alert('Сетевая ошибка при генерации'); resetUI(); } finally { loadingState.classList.add('d-none'); generateBtn.disabled = false; } }); function renderResult(result) { contentContainer.innerHTML = ''; contentContainer.classList.remove('d-none'); actionButtons.classList.remove('d-none'); infoOverlay.classList.remove('d-none'); providerBadge.textContent = result.provider; if (result.is_ai) { providerBadge.className = 'badge badge-ai shadow-sm'; } else { providerBadge.className = 'badge badge-stock shadow-sm'; } if (result.message) { statusMessage.textContent = result.message; statusMessage.classList.remove('d-none'); } if (result.type === 'photo') { const img = document.createElement('img'); img.src = result.url; img.className = 'img-fluid shadow-sm rounded mx-auto d-block'; img.style.maxHeight = '480px'; img.style.objectFit = 'contain'; img.id = 'active-result-img'; contentContainer.appendChild(img); editBtn.classList.remove('d-none'); editBtn.onclick = () => { originalPrompt = result.prompt || originalPrompt; openEditor(result.url); }; } else { const video = document.createElement('video'); video.src = result.url; video.controls = true; video.autoplay = true; video.className = 'rounded mx-auto d-block shadow-sm'; video.style.maxWidth = '100%'; video.style.maxHeight = '480px'; contentContainer.appendChild(video); editBtn.classList.add('d-none'); } downloadBtn.onclick = () => { const a = document.createElement('a'); a.href = result.url; a.download = `generation_${Date.now()}.${result.type === 'photo' ? 'jpg' : 'mp4'}`; document.body.appendChild(a); a.click(); document.body.removeChild(a); }; } function resetUI() { placeholderText.classList.remove('d-none'); contentContainer.classList.add('d-none'); actionButtons.classList.add('d-none'); infoOverlay.classList.add('d-none'); } // Editor Logic function openEditor(url) { currentImage = new Image(); currentImage.crossOrigin = "Anonymous"; currentImage.src = url; currentImage.onload = () => { editorCanvas.width = currentImage.width; editorCanvas.height = currentImage.height; applyFilters(); editorModal.show(); }; } function applyFilters() { if (!currentImage) return; let filters = ''; filterRanges.forEach(range => { const filter = range.dataset.filter; const value = range.value; if (filter === 'brightness' || filter === 'contrast' || filter === 'saturate') { filters += `${filter}(${value}%) `; } else if (filter === 'blur') { filters += `${filter}(${value}px) `; } else { filters += `${filter}(${value}%) `; } }); ctx.filter = filters; ctx.clearRect(0, 0, editorCanvas.width, editorCanvas.height); ctx.drawImage(currentImage, 0, 0); } filterRanges.forEach(range => { range.addEventListener('input', applyFilters); }); resetFiltersBtn.addEventListener('click', () => { filterRanges.forEach(range => { if (range.dataset.filter === 'brightness' || range.dataset.filter === 'contrast' || range.dataset.filter === 'saturate') { range.value = 100; } else { range.value = 0; } }); applyFilters(); }); saveEditedBtn.addEventListener('click', () => { const link = document.createElement('a'); link.download = `edited_${Date.now()}.png`; link.href = editorCanvas.toDataURL('image/png'); link.click(); }); // AI Magic Handlers async function performAiEdit(action, customPrompt = '') { if (!currentImage) return; editorLoading.classList.remove('d-none'); editorLoading.classList.add('d-flex'); try { const response = await fetch('api/edit.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: action, original_prompt: originalPrompt, edit_prompt: customPrompt, image_url: currentImage.src }) }); const result = await response.json(); if (result.success) { // Load new image into canvas const newImg = new Image(); newImg.crossOrigin = "Anonymous"; newImg.src = result.url + '?t=' + Date.now(); newImg.onload = () => { currentImage = newImg; editorCanvas.width = newImg.width; editorCanvas.height = newImg.height; applyFilters(); editorLoading.classList.add('d-none'); editorLoading.classList.remove('d-flex'); }; } else { alert('Ошибка ИИ: ' + (result.error || 'Не удалось применить изменения')); editorLoading.classList.add('d-none'); editorLoading.classList.remove('d-flex'); } } catch (error) { console.error('AI Edit error:', error); alert('Сетевая ошибка при работе с ИИ'); editorLoading.classList.add('d-none'); editorLoading.classList.remove('d-flex'); } } applyAiMagicBtn.addEventListener('click', () => { const prompt = aiEditPrompt.value.trim(); if (!prompt) { alert('Введите описание изменений'); return; } performAiEdit('magic', prompt); }); removeBgBtn.addEventListener('click', () => { performAiEdit('remove_bg'); }); upscaleBtn.addEventListener('click', () => { performAiEdit('upscale'); }); // History Edit Buttons document.addEventListener('click', (e) => { if (e.target.closest('.history-edit-btn')) { const btn = e.target.closest('.history-edit-btn'); const url = btn.dataset.url; const card = btn.closest('.card'); originalPrompt = card.querySelector('.card-text').textContent; openEditor(url); } }); });