WIP file drop server, no downloads yet

This commit is contained in:
xenofem 2022-04-26 23:54:29 -04:00
commit 20da86132b
12 changed files with 3294 additions and 0 deletions

22
static/index.html Normal file
View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" type="text/css" href="transbeam.css"/>
<title>Upload Test</title>
</head>
<body>
<div>
<label>
<span class="fake_button" id="file_input_message">Select files to upload...</span>
<input type="file" multiple id="file_input"/>
</label>
</div>
<button id="upload" disabled>Upload</button>
<h2>Files selected:</h2>
<ul id="file_list">
</ul>
<script src="upload.js"></script>
</body>
</html>

24
static/transbeam.css Normal file
View file

@ -0,0 +1,24 @@
input[type="file"] {
display: none;
}
button, .fake_button {
font-size: 18px;
font-family: sans-serif;
color: #000;
background-color: #ccc;
border: 1px solid #bbb;
border-radius: 4px;
padding: 6px 12px;
cursor: pointer;
}
button:hover, .fake_button:hover {
background-color: #aaa;
}
button:disabled, button:disabled:hover {
color: #aaa;
background-color: #eee;
border-color: #ddd;
}

105
static/upload.js Normal file
View file

@ -0,0 +1,105 @@
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();
}
});
})