|
@@ -310,6 +310,7 @@ function setupEventListeners() {
|
|
|
formData.append('file', file);
|
|
formData.append('file', file);
|
|
|
formData.append('user_session', getUserSession());
|
|
formData.append('user_session', getUserSession());
|
|
|
formData.append('duration_hours', duration);
|
|
formData.append('duration_hours', duration);
|
|
|
|
|
+ let waitingTimeout, errorTimeout;
|
|
|
try {
|
|
try {
|
|
|
const xhr = new XMLHttpRequest();
|
|
const xhr = new XMLHttpRequest();
|
|
|
xhr.upload.addEventListener('progress', function(e) {
|
|
xhr.upload.addEventListener('progress', function(e) {
|
|
@@ -318,8 +319,12 @@ function setupEventListeners() {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
xhr.addEventListener('load', function() {
|
|
xhr.addEventListener('load', function() {
|
|
|
- // Solo marcar 100% cuando el servidor responde
|
|
|
|
|
|
|
+ clearTimeout(waitingTimeout);
|
|
|
|
|
+ clearTimeout(errorTimeout);
|
|
|
updateProgress(file.size, file.size, true);
|
|
updateProgress(file.size, file.size, true);
|
|
|
|
|
+ document.getElementById('uploadSpeed').textContent = '';
|
|
|
|
|
+ document.getElementById('timeRemaining').textContent = '';
|
|
|
|
|
+ document.getElementById('waitingServer')?.remove();
|
|
|
if (xhr.status === 200) {
|
|
if (xhr.status === 200) {
|
|
|
const result = JSON.parse(xhr.responseText);
|
|
const result = JSON.parse(xhr.responseText);
|
|
|
if (result.success) {
|
|
if (result.success) {
|
|
@@ -334,8 +339,35 @@ function setupEventListeners() {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
xhr.addEventListener('error', function() {
|
|
xhr.addEventListener('error', function() {
|
|
|
|
|
+ clearTimeout(waitingTimeout);
|
|
|
|
|
+ clearTimeout(errorTimeout);
|
|
|
|
|
+ document.getElementById('waitingServer')?.remove();
|
|
|
showToast('Network error while uploading', 'error');
|
|
showToast('Network error while uploading', 'error');
|
|
|
});
|
|
});
|
|
|
|
|
+ xhr.upload.addEventListener('load', function() {
|
|
|
|
|
+ // Barra llegó a 100%, pero aún esperando respuesta
|
|
|
|
|
+ updateProgress(file.size, file.size, true);
|
|
|
|
|
+ let waiting = document.getElementById('waitingServer');
|
|
|
|
|
+ if (!waiting) {
|
|
|
|
|
+ waiting = document.createElement('div');
|
|
|
|
|
+ waiting.id = 'waitingServer';
|
|
|
|
|
+ waiting.className = 'text-xs text-blue-600 dark:text-blue-400 mt-2 flex items-center gap-2';
|
|
|
|
|
+ waiting.innerHTML = '<svg class="animate-spin h-4 w-4 mr-1 inline" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path></svg>Waiting for server confirmation...';
|
|
|
|
|
+ uploadProgress.appendChild(waiting);
|
|
|
|
|
+ }
|
|
|
|
|
+ // Si pasan 60s tras barra 100%, mostrar advertencia
|
|
|
|
|
+ waitingTimeout = setTimeout(() => {
|
|
|
|
|
+ waiting.textContent = 'The upload is taking longer than expected. Please check your connection.';
|
|
|
|
|
+ }, 60000);
|
|
|
|
|
+ // Si pasan 2 minutos, mostrar error y permitir reintentar
|
|
|
|
|
+ errorTimeout = setTimeout(() => {
|
|
|
|
|
+ waiting.remove();
|
|
|
|
|
+ showToast('Upload failed: server did not respond. Please try again.', 'error');
|
|
|
|
|
+ uploadBtn.disabled = false;
|
|
|
|
|
+ uploadBtnText.textContent = 'Upload File';
|
|
|
|
|
+ uploadProgress.classList.add('hidden');
|
|
|
|
|
+ }, 120000);
|
|
|
|
|
+ });
|
|
|
xhr.open('POST', '/upload');
|
|
xhr.open('POST', '/upload');
|
|
|
xhr.send(formData);
|
|
xhr.send(formData);
|
|
|
} catch (error) {
|
|
} catch (error) {
|