146 lines
5.1 KiB
JavaScript
146 lines
5.1 KiB
JavaScript
(() => {
|
|
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 <label for="file-input" class="link">browse</label>';
|
|
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 <label for="file-input" class="link">browse</label>';
|
|
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';
|
|
}
|
|
})();
|