"use strict";
const id = document?.cookie?.split(';')[0]?.split('=')[1];
function deleteAllCookies() {
const cookies = document.cookie.split(";");
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i];
const eqPos = cookie.indexOf("=");
const name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
}
deleteAllCookies();
window.addEventListener("load", () => {
const fisk = document.getElementById('fisk');
const pingPong = document.getElementById('pingpong');
const dialog = document.getElementById('dialog');
const proto = (window.location.protocol === 'https:') ? 'wss' : 'ws';
const host = (window.location.hostname);
const path = window.location.pathname;
const wsUrl = `${proto}://${host}${path}socket`;
const webSocket = new WebSocket(wsUrl);
console.log('Connecting to ' + wsUrl);
function showDiag() {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.multiple = false;
fileInput.addEventListener('change', async () => {
if (fileInput.files) {
fileInput.style.display = 'none';
const f = fileInput.files[0];
const abuf = await f.arrayBuffer();
const bytes = new Uint8Array(abuf);
webSocket.send(JSON.stringify({
type: 'start',
name: f.name,
ftype: f.type,
len: bytes.length,
}));
let cs = 0;
let str = '';
const lastByte = bytes.length - 1;
for (let i = 0; i < bytes.length; i++) {
str += String.fromCharCode(bytes[i]);
cs++;
if (cs === 2048 || i === lastByte) {
webSocket.send(JSON.stringify({
type: 'data',
data: btoa(str)
}));
cs = 0;
str = '';
}
const pct = Math.floor(i / bytes.length * 100);
fisk.innerHTML = `Sending ${f.name} (${pct}% - ${i} / ${bytes.length})`;
}
fisk.innerHTML = `Sent ${f.name}`;
fileInput.style.display = 'block';
}
});
dialog.append(fileInput);
}
webSocket.onopen = (e) => {
if (id) {
webSocket.send(JSON.stringify({ type: 'join', id }));
}
else {
webSocket.send(JSON.stringify({ type: 'host' }));
}
};
let pingTime = new Date().getTime();
let inbuf = new Uint8Array(0);
let inname = '';
let intype = '';
let curByte = 0;
webSocket.onmessage = (e) => {
const d = JSON.parse(e.data);
if (d.type === 'start') {
inbuf = new Uint8Array(d.len);
inname = d.name;
intype = d.ftype;
curByte = 0;
}
if (d.type === 'data') {
const pct = Math.floor(curByte / inbuf.byteLength * 100);
fisk.innerHTML = `Receiving ${inname} (${pct}% - ${curByte} / ${inbuf.byteLength})`;
const binStr = atob(d.data);
for (let i = 0; i < binStr.length; i++) {
inbuf[curByte] = binStr.charCodeAt(i);
curByte++;
}
if (curByte === inbuf.byteLength) {
fisk.innerHTML = `Received ${inname} (${pct}% - ${curByte} / ${inbuf.byteLength})`;
const blob = new Blob([inbuf], { type: intype });
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = inname;
link.click();
}
}
if (d.type === 'waiting') {
fisk.innerHTML = `Send this link to a friend you wish to transfer files with (click to copy)
${d.url}
`;
}
if (d.type === 'hosting') {
showDiag();
fisk.innerHTML = `Your friend has connected`;
}
if (d.type === 'pong') {
const latency = (new Date().getTime()) - pingTime;
setTimeout(() => {
pingTime = new Date().getTime();
webSocket.send(JSON.stringify({
type: 'ping',
latency
}));
pingPong.innerHTML = `Latency: ${latency} ms.`;
}, 2000);
}
if (d.type === 'ping') {
webSocket.send(JSON.stringify({ type: 'pong' }));
pingPong.innerHTML = `Latency: ${d.latency} ms.`;
}
if (d.type === 'joined') {
showDiag();
fisk.innerHTML = `Joined ${id}`;
}
if (d.type === 'error') {
fisk.innerHTML = d.message;
deleteAllCookies();
webSocket.send(JSON.stringify({ type: 'host' }));
}
};
webSocket.onclose = () => {
dialog.innerHTML = '';
fisk.innerHTML = `Disconnected
`;
};
const f = document.getElementById('file');
if (f) {
f.addEventListener('change', async (event) => {
// I wonder why I left this here..
});
}
});