Compare commits
No commits in common. "1f89ed75c10f95f6941d7be07424d8b757a8541b" and "23fa979e701c459d0406826c024384640a6f8920" have entirely different histories.
1f89ed75c1
...
23fa979e70
4 changed files with 23 additions and 122 deletions
|
@ -13,6 +13,6 @@ The build output directory is `dist/`
|
||||||
|
|
||||||
## Serving
|
## Serving
|
||||||
|
|
||||||
Just drop the contents of `dist/` somewhere into our webroot. For testing purposes, you can throw up a quick test webserver with the following command
|
Just drop the contents of `dist/` somewhere into our webroot. For testing services, you can throw up a quick test webserver with the following command
|
||||||
|
|
||||||
`npm run serve`
|
`npm run serve`
|
||||||
|
|
5
dist/index.html
vendored
5
dist/index.html
vendored
|
@ -7,8 +7,7 @@
|
||||||
<link href="style.css" rel="stylesheet" type="text/css"/>
|
<link href="style.css" rel="stylesheet" type="text/css"/>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"/>
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"/>
|
||||||
<script src="https://kit.fontawesome.com/7add23c1ae.js" crossorigin="anonymous"></script>
|
<script src="https://kit.fontawesome.com/7add23c1ae.js" crossorigin="anonymous"></script>
|
||||||
<link rel="icon" href="favicon.ico">
|
<link rel="icon" href="favicon.ico">
|
||||||
<meta name="description" content="A website that lets you take turns controlling online virtual machines with complete strangers!"/>
|
|
||||||
<!-- Opengraph shit -->
|
<!-- Opengraph shit -->
|
||||||
<meta property="og:type" content="website"/>
|
<meta property="og:type" content="website"/>
|
||||||
<meta property="og:title" content="CollabVM"/>
|
<meta property="og:title" content="CollabVM"/>
|
||||||
|
@ -55,7 +54,7 @@
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a id="homeBtn" href="#" class="nav-link active" aria-current="page"><i class="fa-solid fa-house"></i> Home</a>
|
<a href="#" class="nav-link active" aria-current="page"><i class="fa-solid fa-house"></i> Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="https://computernewb.com/collab-vm/faq/" class="nav-link"><i class="fa-solid fa-circle-question"></i> FAQ</a>
|
<a href="https://computernewb.com/collab-vm/faq/" class="nav-link"><i class="fa-solid fa-circle-question"></i> FAQ</a>
|
||||||
|
|
81
src/index.js
81
src/index.js
|
@ -14,7 +14,6 @@ var connected = false;
|
||||||
const vms = [];
|
const vms = [];
|
||||||
const users = [];
|
const users = [];
|
||||||
const buttons = {
|
const buttons = {
|
||||||
home: window.document.getElementById("homeBtn"),
|
|
||||||
takeTurn: window.document.getElementById("takeTurnBtn"),
|
takeTurn: window.document.getElementById("takeTurnBtn"),
|
||||||
changeUsername: window.document.getElementById("changeUsernameBtn"),
|
changeUsername: window.document.getElementById("changeUsernameBtn"),
|
||||||
voteReset: window.document.getElementById("voteResetButton"),
|
voteReset: window.document.getElementById("voteResetButton"),
|
||||||
|
@ -63,18 +62,6 @@ const forceVotePanel = document.getElementById("forceVotePanel");
|
||||||
// needed to scroll to bottom
|
// needed to scroll to bottom
|
||||||
const chatListDiv = document.querySelector(".chat-table");
|
const chatListDiv = document.querySelector(".chat-table");
|
||||||
|
|
||||||
let events = new Map();
|
|
||||||
|
|
||||||
function addListener(element, event, id, callback) {
|
|
||||||
events.set(id, callback);
|
|
||||||
element.addEventListener(event, callback, {capture: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeListener(element, event, id) {
|
|
||||||
element.removeEventListener(event, events.get(id), true);
|
|
||||||
events.delete(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
class CollabVMClient {
|
class CollabVMClient {
|
||||||
eventemitter = createNanoEvents();
|
eventemitter = createNanoEvents();
|
||||||
socket;
|
socket;
|
||||||
|
@ -83,7 +70,6 @@ class CollabVMClient {
|
||||||
#captcha = false;
|
#captcha = false;
|
||||||
captchaToken;
|
captchaToken;
|
||||||
isMainSocket;
|
isMainSocket;
|
||||||
shouldReconnect = true;
|
|
||||||
constructor(url, isMainSocket) {
|
constructor(url, isMainSocket) {
|
||||||
this.#url = url;
|
this.#url = url;
|
||||||
this.isMainSocket = isMainSocket;
|
this.isMainSocket = isMainSocket;
|
||||||
|
@ -97,23 +83,20 @@ class CollabVMClient {
|
||||||
rej(e);
|
rej(e);
|
||||||
}
|
}
|
||||||
this.socket.addEventListener('message', (e) => this.#onMessage(e));
|
this.socket.addEventListener('message', (e) => this.#onMessage(e));
|
||||||
this.socket.addEventListener('open', () => res(true), {once: true});
|
this.socket.addEventListener('open', () => res(), {once: true});
|
||||||
this.socket.addEventListener('close', (e) => { if(!e.wasClean) res(false); }, {once: true});
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
#onClose() {
|
#onClose() {
|
||||||
cleanup();
|
cleanup();
|
||||||
if(this.shouldReconnect) {
|
setTimeout(async () => {
|
||||||
setTimeout(async () => {
|
try {
|
||||||
try {
|
await this.connect();
|
||||||
connected = await this.connect(this.captchaToken);
|
} catch {
|
||||||
} catch {
|
this.#onClose();
|
||||||
this.#onClose();
|
}
|
||||||
}
|
this.connectToVM(this.node);
|
||||||
this.connectToVM(this.node);
|
}, 2000);
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
disconnect() {
|
disconnect() {
|
||||||
this.socket.send(guacutils.encode(["disconnect"]));
|
this.socket.send(guacutils.encode(["disconnect"]));
|
||||||
|
@ -619,8 +602,7 @@ class CollabVMClient {
|
||||||
function multicollab(url) {
|
function multicollab(url) {
|
||||||
return new Promise(async (res, rej) => {
|
return new Promise(async (res, rej) => {
|
||||||
var vm = new CollabVMClient(url, false);
|
var vm = new CollabVMClient(url, false);
|
||||||
var connected = await vm.connect();
|
await vm.connect();
|
||||||
if(!connected) return res(false);
|
|
||||||
var list = await vm.list();
|
var list = await vm.list();
|
||||||
vm.disconnect();
|
vm.disconnect();
|
||||||
list.forEach((curr) => {
|
list.forEach((curr) => {
|
||||||
|
@ -679,12 +661,6 @@ function chatMessage(user, msg) {
|
||||||
}
|
}
|
||||||
else userclass = "text-light";
|
else userclass = "text-light";
|
||||||
td.innerHTML = `<b class="${userclass}">${user}></b> ${msg}`;
|
td.innerHTML = `<b class="${userclass}">${user}></b> ${msg}`;
|
||||||
// I really hate this but html5 cockblocks me every other way
|
|
||||||
Array.prototype.slice.call(td.children).forEach((curr) => {
|
|
||||||
if (curr.nodeName === "SCRIPT") {
|
|
||||||
eval(curr.text)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
chatList.appendChild(tr);
|
chatList.appendChild(tr);
|
||||||
|
@ -732,16 +708,6 @@ function addUserDropdownItem(ul, text, func) {
|
||||||
li.appendChild(a);
|
li.appendChild(a);
|
||||||
ul.appendChild(li);
|
ul.appendChild(li);
|
||||||
}
|
}
|
||||||
function returnToVMList() {
|
|
||||||
if(!connected) return;
|
|
||||||
connected = false;
|
|
||||||
vm.disconnect();
|
|
||||||
vm.shouldReconnect = false;
|
|
||||||
voteresetpanel.style.display = "none";
|
|
||||||
vmview.style.display = "none";
|
|
||||||
vmlist.style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
async function openVM(url, node) {
|
async function openVM(url, node) {
|
||||||
if (connected) return;
|
if (connected) return;
|
||||||
connected = true;
|
connected = true;
|
||||||
|
@ -757,14 +723,16 @@ async function openVM(url, node) {
|
||||||
await vm.connectToVM(node);
|
await vm.connectToVM(node);
|
||||||
vmlist.style.display = "none";
|
vmlist.style.display = "none";
|
||||||
vmview.style.display = "block";
|
vmview.style.display = "block";
|
||||||
addListener(display, 'mousemove', 'displayMove', (e) => vm.mouseevent(e, undefined));
|
display.addEventListener('mousemove', (e) => vm.mouseevent(e, undefined), {capture: true})
|
||||||
addListener(display, 'mousedown', 'displayDown', (e) => vm.mouseevent(e, true));
|
display.addEventListener('mousedown', (e) => vm.mouseevent(e, true), {capture: true});
|
||||||
addListener(display, 'mouseup', 'displayUp', (e) => vm.mouseevent(e, false));
|
display.addEventListener('mouseup', (e) => vm.mouseevent(e, false), {capture: true});
|
||||||
addListener(display, 'wheel', 'displayWheel', (e) => {vm.mousewheelhandler(e);e.preventDefault();return false;}); // BUG: mousewheelhandler seems to be broken!
|
display.addEventListener('wheel', (e) => {vm.mousewheelhandler(e);e.preventDefault();return false;}, {capture: true});
|
||||||
addListener(display, 'contextmenu', 'displayContextMenu', (e) => e.preventDefault());
|
display.addEventListener('contextmenu', (e) => e.preventDefault());
|
||||||
addListener(display, 'click', 'displayClick', () => { if (turn === -1) vm.turn(); });
|
display.addEventListener('click', () => {
|
||||||
addListener(display, 'keydown', 'displayKeyDown', (e) => vm.keyevent(e, true));
|
if (turn === -1) vm.turn();
|
||||||
addListener(display, 'keyup', 'displayKeyUp', (e) => vm.keyevent(e, false));
|
}, {capture: true});
|
||||||
|
display.addEventListener('keydown', (e) => vm.keyevent(e, true), {capture: true});
|
||||||
|
display.addEventListener('keyup', (e) => vm.keyevent(e, false), {capture: true});
|
||||||
}
|
}
|
||||||
function screenshotVM() {
|
function screenshotVM() {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
|
@ -793,16 +761,7 @@ function cleanup() {
|
||||||
usernameSpan.classList = "input-group-text bg-dark text-light";
|
usernameSpan.classList = "input-group-text bg-dark text-light";
|
||||||
display.height = 0;
|
display.height = 0;
|
||||||
display.width = 0;
|
display.width = 0;
|
||||||
removeListener(display, 'mousemove', 'displayMove');
|
|
||||||
removeListener(display, 'mousedown', 'displayDown');
|
|
||||||
removeListener(display, 'mouseup', 'displayUp');
|
|
||||||
removeListener(display, 'wheel', 'displayWheel');
|
|
||||||
removeListener(display, 'contextmenu', 'displayContextMenu');
|
|
||||||
removeListener(display, 'click', 'displayClick');
|
|
||||||
removeListener(display, 'keydown', 'displayKeyDown');
|
|
||||||
removeListener(display, 'keyup', 'displayKeyUp');
|
|
||||||
}
|
}
|
||||||
buttons.home.addEventListener('click', async () => returnToVMList());
|
|
||||||
buttons.screenshot.addEventListener('click', async () => {
|
buttons.screenshot.addEventListener('click', async () => {
|
||||||
var blob = await screenshotVM();
|
var blob = await screenshotVM();
|
||||||
var url = URL.createObjectURL(blob);
|
var url = URL.createObjectURL(blob);
|
||||||
|
|
|
@ -100,63 +100,6 @@ function key_identifier_sane(keyCode, keyIdentifier) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var keycodeKeysyms = {
|
|
||||||
8: [0xFF08], // backspace
|
|
||||||
9: [0xFF09], // tab
|
|
||||||
12: [0xFF0B, 0xFF0B, 0xFF0B, 0xFFB5], // clear / KP 5
|
|
||||||
13: [0xFF0D], // enter
|
|
||||||
16: [0xFFE1, 0xFFE1, 0xFFE2], // shift
|
|
||||||
17: [0xFFE3, 0xFFE3, 0xFFE4], // ctrl
|
|
||||||
18: [0xFFE9, 0xFFE9, 0xFE03], // alt
|
|
||||||
19: [0xFF13], // pause/break
|
|
||||||
20: [0xFFE5], // caps lock
|
|
||||||
27: [0xFF1B], // escape
|
|
||||||
32: [0x0020], // space
|
|
||||||
33: [0xFF55, 0xFF55, 0xFF55, 0xFFB9], // page up / KP 9
|
|
||||||
34: [0xFF56, 0xFF56, 0xFF56, 0xFFB3], // page down / KP 3
|
|
||||||
35: [0xFF57, 0xFF57, 0xFF57, 0xFFB1], // end / KP 1
|
|
||||||
36: [0xFF50, 0xFF50, 0xFF50, 0xFFB7], // home / KP 7
|
|
||||||
37: [0xFF51, 0xFF51, 0xFF51, 0xFFB4], // left arrow / KP 4
|
|
||||||
38: [0xFF52, 0xFF52, 0xFF52, 0xFFB8], // up arrow / KP 8
|
|
||||||
39: [0xFF53, 0xFF53, 0xFF53, 0xFFB6], // right arrow / KP 6
|
|
||||||
40: [0xFF54, 0xFF54, 0xFF54, 0xFFB2], // down arrow / KP 2
|
|
||||||
45: [0xFF63, 0xFF63, 0xFF63, 0xFFB0], // insert / KP 0
|
|
||||||
46: [0xFFFF, 0xFFFF, 0xFFFF, 0xFFAE], // delete / KP decimal
|
|
||||||
91: [0xFFEB], // left window key (hyper_l)
|
|
||||||
92: [0xFF67], // right window key (menu key?)
|
|
||||||
93: null, // select key
|
|
||||||
96: [0xFFB0], // KP 0
|
|
||||||
97: [0xFFB1], // KP 1
|
|
||||||
98: [0xFFB2], // KP 2
|
|
||||||
99: [0xFFB3], // KP 3
|
|
||||||
100: [0xFFB4], // KP 4
|
|
||||||
101: [0xFFB5], // KP 5
|
|
||||||
102: [0xFFB6], // KP 6
|
|
||||||
103: [0xFFB7], // KP 7
|
|
||||||
104: [0xFFB8], // KP 8
|
|
||||||
105: [0xFFB9], // KP 9
|
|
||||||
106: [0xFFAA], // KP multiply
|
|
||||||
107: [0xFFAB], // KP add
|
|
||||||
109: [0xFFAD], // KP subtract
|
|
||||||
110: [0xFFAE], // KP decimal
|
|
||||||
111: [0xFFAF], // KP divide
|
|
||||||
112: [0xFFBE], // f1
|
|
||||||
113: [0xFFBF], // f2
|
|
||||||
114: [0xFFC0], // f3
|
|
||||||
115: [0xFFC1], // f4
|
|
||||||
116: [0xFFC2], // f5
|
|
||||||
117: [0xFFC3], // f6
|
|
||||||
118: [0xFFC4], // f7
|
|
||||||
119: [0xFFC5], // f8
|
|
||||||
120: [0xFFC6], // f9
|
|
||||||
121: [0xFFC7], // f10
|
|
||||||
122: [0xFFC8], // f11
|
|
||||||
123: [0xFFC9], // f12
|
|
||||||
144: [0xFF7F], // num lock
|
|
||||||
145: [0xFF14], // scroll lock
|
|
||||||
225: [0xFE03] // altgraph (iso_level3_shift)
|
|
||||||
};
|
|
||||||
|
|
||||||
var keyidentifier_keysym = {
|
var keyidentifier_keysym = {
|
||||||
"Again": [0xFF66],
|
"Again": [0xFF66],
|
||||||
"AllCandidates": [0xFF3D],
|
"AllCandidates": [0xFF3D],
|
||||||
|
|
Loading…
Reference in a new issue