Spaces:
Paused
Paused
| document.addEventListener('DOMContentLoaded', function() { | |
| const form = document.getElementById('translationForm'); | |
| const progressArea = document.getElementById('progressArea'); | |
| const progressBar = document.querySelector('.progress-bar'); | |
| const progressText = document.getElementById('progressText'); | |
| const resultArea = document.getElementById('resultArea'); | |
| const mediaPlayer = document.getElementById('mediaPlayer'); | |
| const downloadBtn = document.getElementById('downloadBtn'); | |
| const submitBtn = document.getElementById('submitBtn'); | |
| // Retry configuration | |
| const MAX_RETRIES = 3; | |
| const RETRY_DELAY = 5000; // 5 seconds | |
| async function delay(ms) { | |
| return new Promise(resolve => setTimeout(resolve, ms)); | |
| } | |
| async function submitWithRetry(formData, retryCount = 0) { | |
| try { | |
| const response = await fetch('/api/translate', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| if (response.status === 429) { // Rate limit error | |
| if (retryCount < MAX_RETRIES) { | |
| const waitTime = (retryCount + 1) * RETRY_DELAY; | |
| updateProgress(50, `Rate limit reached. Retrying in ${waitTime/1000} seconds... (Attempt ${retryCount + 1}/${MAX_RETRIES})`); | |
| await delay(waitTime); | |
| return submitWithRetry(formData, retryCount + 1); | |
| } else { | |
| throw new Error('Rate limit exceeded. Please try again later.'); | |
| } | |
| } | |
| if (!response.ok) { | |
| const error = await response.text(); | |
| throw new Error(error); | |
| } | |
| return response; | |
| } catch (error) { | |
| if (error.message.includes('Rate limit exceeded')) { | |
| throw error; | |
| } | |
| throw new Error(`Request failed: ${error.message}`); | |
| } | |
| } | |
| form.addEventListener('submit', async function(e) { | |
| e.preventDefault(); | |
| // Show progress and disable submit button | |
| progressArea.classList.remove('d-none'); | |
| submitBtn.disabled = true; | |
| progressBar.style.width = '0%'; | |
| resultArea.classList.add('d-none'); | |
| downloadBtn.classList.add('d-none'); | |
| // Remove any previous error styling | |
| progressBar.classList.remove('bg-danger'); | |
| const updateProgress = (percent, message) => { | |
| progressBar.style.width = `${percent}%`; | |
| progressText.textContent = message; | |
| }; | |
| try { | |
| const formData = new FormData(this); | |
| const file = formData.get('file'); | |
| // Validate file size (max 500MB) | |
| if (file.size > 500 * 1024 * 1024) { | |
| throw new Error('File size exceeds 500MB limit'); | |
| } | |
| updateProgress(10, 'Uploading file...'); | |
| try { | |
| const response = await submitWithRetry(formData); | |
| const blob = await response.blob(); | |
| const url = URL.createObjectURL(blob); | |
| // Update UI based on file type | |
| const outputType = formData.get('output_type'); | |
| const mediaElement = document.createElement(outputType === 'video' ? 'video' : 'audio'); | |
| mediaElement.src = url; | |
| mediaElement.controls = true; | |
| mediaElement.classList.add('w-100'); | |
| // Clear previous media player content | |
| mediaPlayer.innerHTML = ''; | |
| mediaPlayer.appendChild(mediaElement); | |
| // Setup download button | |
| downloadBtn.href = url; | |
| downloadBtn.download = `translated_media.${outputType === 'video' ? 'mp4' : 'mp3'}`; | |
| // Show results | |
| const thumbnailHTML = ` | |
| <div class="alert alert-success"> | |
| <div class="d-flex align-items-center"> | |
| <img src="${url}" alt="Video thumbnail" style="width: 210px; height: 120px; object-fit: cover; margin: 0 auto; border-radius: 9px; margin: 10px auto;"> | |
| <div> | |
| <strong>Video úspěšně staženo!</strong> | |
| <br> | |
| <small class="text-muted">Připraveno ke zpracování</small> | |
| </div> | |
| </div> | |
| </div>`; | |
| resultArea.innerHTML = thumbnailHTML; | |
| resultArea.classList.remove('d-none'); | |
| downloadBtn.classList.remove('d-none'); | |
| updateProgress(100, 'Translation complete!'); | |
| } catch (error) { | |
| throw error; | |
| } | |
| } catch (error) { | |
| console.error('Error:', error); | |
| progressBar.classList.add('bg-danger'); | |
| updateProgress(100, `Error: ${error.message}`); | |
| } finally { | |
| submitBtn.disabled = false; | |
| } | |
| }); | |
| }); | |