(() => { const dropzone = document.getElementById('dropzone'); const fileInput = document.getElementById('file-input'); const options = document.getElementById('options'); const uploadBtn = document.getElementById('upload-btn'); const progressSection = document.getElementById('progress-section'); const progressFilename = document.getElementById('progress-filename'); const progressFill = document.getElementById('progress-fill'); const progressText = document.getElementById('progress-text'); const result = document.getElementById('result'); const resultUrl = document.getElementById('result-url'); const copyBtn = document.getElementById('copy-btn'); const resultDelete = document.getElementById('result-delete'); const resultExpiry = document.getElementById('result-expiry'); const errorDiv = document.getElementById('error'); let selectedFile = null; // Drag and drop dropzone.addEventListener('dragover', (e) => { e.preventDefault(); dropzone.classList.add('drag-over'); }); dropzone.addEventListener('dragleave', () => { dropzone.classList.remove('drag-over'); }); dropzone.addEventListener('drop', (e) => { e.preventDefault(); dropzone.classList.remove('drag-over'); if (e.dataTransfer.files.length > 0) { selectFile(e.dataTransfer.files[0]); } }); dropzone.addEventListener('click', () => fileInput.click()); fileInput.addEventListener('change', () => { if (fileInput.files.length > 0) { selectFile(fileInput.files[0]); } }); function selectFile(file) { selectedFile = file; dropzone.querySelector('p').textContent = file.name + ' (' + formatSize(file.size) + ')'; options.classList.remove('hidden'); result.classList.add('hidden'); errorDiv.classList.add('hidden'); } uploadBtn.addEventListener('click', () => { if (!selectedFile) return; upload(selectedFile); }); function upload(file) { const formData = new FormData(); formData.append('file', file); const expires = document.getElementById('expires').value; if (expires) formData.append('expires_in', expires); const password = document.getElementById('password').value; if (password) formData.append('password', password); const xhr = new XMLHttpRequest(); // Show progress options.classList.add('hidden'); dropzone.classList.add('hidden'); progressSection.classList.remove('hidden'); progressFilename.textContent = file.name; errorDiv.classList.add('hidden'); xhr.upload.addEventListener('progress', (e) => { if (e.lengthComputable) { const pct = Math.round((e.loaded / e.total) * 100); progressFill.style.width = pct + '%'; progressText.textContent = pct + '% — ' + formatSize(e.loaded) + ' / ' + formatSize(e.total); } }); xhr.addEventListener('load', () => { progressSection.classList.add('hidden'); if (xhr.status === 201) { const data = JSON.parse(xhr.responseText); showResult(data); } else { showError(xhr.responseText || 'Upload failed'); } }); xhr.addEventListener('error', () => { progressSection.classList.add('hidden'); showError('Network error — upload failed'); }); xhr.open('POST', '/upload'); xhr.send(formData); } function showResult(data) { result.classList.remove('hidden'); resultUrl.value = data.url; resultDelete.textContent = 'Delete: curl -X DELETE -H "Authorization: Bearer ' + data.delete_token + '" ' + data.delete_url; if (data.expires_at) { resultExpiry.textContent = 'Expires: ' + new Date(data.expires_at).toLocaleString(); } else { resultExpiry.textContent = ''; } // Reset for another upload dropzone.classList.remove('hidden'); dropzone.querySelector('p').innerHTML = 'Drop a file here or '; selectedFile = null; } function showError(msg) { errorDiv.textContent = msg; errorDiv.classList.remove('hidden'); dropzone.classList.remove('hidden'); dropzone.querySelector('p').innerHTML = 'Drop a file here or '; selectedFile = null; } copyBtn.addEventListener('click', () => { resultUrl.select(); navigator.clipboard.writeText(resultUrl.value).then(() => { copyBtn.textContent = 'Copied!'; setTimeout(() => { copyBtn.textContent = 'Copy'; }, 2000); }); }); function formatSize(bytes) { if (bytes < 1024) return bytes + ' B'; if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB'; } })();