let files = []; let socket = null; let fileIndex = 0; let byteIndex = 0; function sendMetadata() { const metadata = files.map((file) => ({ name: file.name, size: file.size, modtime: file.lastModified, })); socket.send(JSON.stringify(metadata)); } function finishSending() { if (socket.bufferedAmount > 0) { window.setTimeout(finishSending, 1000); return; } socket.close(); alert("done"); } function sendData() { if (fileIndex >= files.length) { finishSending(); } const currentFile = files[fileIndex]; if (byteIndex < currentFile.size) { const endpoint = Math.min(byteIndex+8192, currentFile.size); const data = currentFile.slice(byteIndex, endpoint); socket.send(data); byteIndex = endpoint; } else { fileIndex += 1; byteIndex = 0; sendData(); } } const fileInput = document.getElementById('file_input'); const fileInputMessage = document.getElementById('file_input_message'); const fileList = document.getElementById('file_list'); const uploadButton = document.getElementById('upload'); function updateButtons() { if (files.length === 0) { uploadButton.disabled = true; fileInputMessage.textContent = 'Select files to upload...'; } else { uploadButton.disabled = false; fileInputMessage.textContent = 'Select more files to upload...'; } } updateButtons(); function addFile(newFile) { if (files.some((oldFile) => newFile.name === oldFile.name)) { return; } files.push(newFile); const listEntry = document.createElement('li'); const deleteButton = document.createElement('button'); deleteButton.textContent = 'x'; deleteButton.addEventListener('click', () => { removeFile(newFile.name); listEntry.remove(); updateButtons(); }); const entryName = document.createElement('span'); entryName.textContent = newFile.name; listEntry.appendChild(deleteButton); listEntry.appendChild(entryName); fileList.appendChild(listEntry); } function removeFile(name) { files = files.filter((file) => file.name !== name); } fileInput.addEventListener('input', (e) => { for (const file of e.target.files) { addFile(file); } updateButtons(); e.target.value = ''; }); uploadButton.addEventListener('click', (e) => { if (files.length === 0) { return; } fileInput.disabled = true; for (const button of document.getElementsByTagName('button')) { button.disabled = true; } socket = new WebSocket('ws://localhost:3000/upload'); socket.addEventListener('open', sendMetadata); socket.addEventListener('message', (msg) => { if (msg.data === 'ack') { sendData(); } }); })