Spaces:
Sleeping
Sleeping
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; | |
} | |
}); | |
}); | |