|
|
@@ -108,14 +108,19 @@ function getTimeRemaining(expirationDate) {
|
|
|
// Progreso de subida
|
|
|
let uploadStartTime = 0;
|
|
|
let uploadedBytes = 0;
|
|
|
-function updateProgress(loaded, total) {
|
|
|
- const percent = Math.round((loaded / total) * 100);
|
|
|
+function updateProgress(loaded, total, isDone = false) {
|
|
|
+ const percent = isDone ? 100 : Math.round((loaded / total) * 100);
|
|
|
const progressBar = document.getElementById('progressBar');
|
|
|
const progressPercent = document.getElementById('progressPercent');
|
|
|
const uploadSpeed = document.getElementById('uploadSpeed');
|
|
|
const timeRemaining = document.getElementById('timeRemaining');
|
|
|
progressBar.style.width = percent + '%';
|
|
|
progressPercent.textContent = percent + '%';
|
|
|
+ if (isDone) {
|
|
|
+ uploadSpeed.textContent = '';
|
|
|
+ timeRemaining.textContent = '';
|
|
|
+ return;
|
|
|
+ }
|
|
|
const elapsed = (Date.now() - uploadStartTime) / 1000;
|
|
|
const speed = loaded / elapsed;
|
|
|
const speedMB = (speed / (1024 * 1024)).toFixed(2);
|
|
|
@@ -190,9 +195,12 @@ async function loadUserFiles() {
|
|
|
<div class="text-right">
|
|
|
<p class="text-xs text-gray-500 dark:text-gray-400 file-remaining-time" data-expiration="${file.expiration_date}">${getTimeRemaining(file.expiration_date)}</p>
|
|
|
</div>
|
|
|
- <a href="${file.download_url}" class="inline-flex items-center px-3 py-1 text-xs font-medium text-blue-600 dark:text-blue-400 bg-blue-100 dark:bg-blue-900/30 hover:bg-blue-200 dark:hover:bg-blue-900/50 rounded-full transition-colors">
|
|
|
+ <a href="${file.download_url}" class="inline-flex items-center px-3 py-1 text-xs font-medium text-blue-600 dark:text-blue-400 bg-blue-100 dark:bg-blue-900/30 hover:bg-blue-200 dark:hover:bg-blue-900/50 rounded-full transition-colors" target="_blank">
|
|
|
Download
|
|
|
</a>
|
|
|
+ <button onclick="copyDownloadUrl('${file.download_url}')" class="inline-flex items-center px-3 py-1 text-xs font-medium text-gray-700 dark:text-gray-200 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-full transition-colors">
|
|
|
+ Copy Link
|
|
|
+ </button>
|
|
|
<button onclick="deleteFile('${file.id}')" class="inline-flex items-center px-3 py-1 text-xs font-medium text-red-600 dark:text-red-400 bg-red-100 dark:bg-red-900/30 hover:bg-red-200 dark:hover:bg-red-900/50 rounded-full transition-colors">
|
|
|
Delete
|
|
|
</button>
|
|
|
@@ -310,6 +318,8 @@ function setupEventListeners() {
|
|
|
}
|
|
|
});
|
|
|
xhr.addEventListener('load', function() {
|
|
|
+ // Solo marcar 100% cuando el servidor responde
|
|
|
+ updateProgress(file.size, file.size, true);
|
|
|
if (xhr.status === 200) {
|
|
|
const result = JSON.parse(xhr.responseText);
|
|
|
if (result.success) {
|
|
|
@@ -355,4 +365,12 @@ function updateRemainingTimes() {
|
|
|
const expiration = el.getAttribute('data-expiration');
|
|
|
el.textContent = getTimeRemaining(expiration);
|
|
|
});
|
|
|
+}
|
|
|
+
|
|
|
+window.copyDownloadUrl = function(url) {
|
|
|
+ navigator.clipboard.writeText(url).then(() => {
|
|
|
+ showToast('Download link copied!');
|
|
|
+ }, () => {
|
|
|
+ showToast('Failed to copy link', 'error');
|
|
|
+ });
|
|
|
}
|