File size: 5,231 Bytes
ad91627
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22a56cf
 
 
 
 
 
 
 
 
 
 
 
ad91627
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
939fd2e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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;
        }
    });
});