From fa2222eab999a1b643453db37a7f6a350d27d548 Mon Sep 17 00:00:00 2001
From: Sami Spets <savasp@utu.fi>
Date: Tue, 29 Oct 2019 14:28:09 +0200
Subject: [PATCH] Handshake now works when client tries to connect via
 websocket

---
 web-service/server/public/js/lib/Peer.js      | 243 ------------------
 web-service/server/src/index.js               |   2 +-
 web-service/server/src/peer.js                |  14 +-
 .../server/{ => src}/public/css/index.css     |   0
 .../server/{ => src}/public/index.html        |   1 -
 .../server/{ => src}/public/js/index.js       |  24 +-
 .../server/{ => src}/public/js/lib/bundle.js  | 225 +++++++++++++---
 .../{ => src}/public/js/lib/libde265.min.js   |   0
 .../{ => src}/public/js/lib/msgpack5.min.js   |   0
 9 files changed, 221 insertions(+), 288 deletions(-)
 delete mode 100644 web-service/server/public/js/lib/Peer.js
 rename web-service/server/{ => src}/public/css/index.css (100%)
 rename web-service/server/{ => src}/public/index.html (89%)
 rename web-service/server/{ => src}/public/js/index.js (90%)
 rename web-service/server/{ => src}/public/js/lib/bundle.js (96%)
 rename web-service/server/{ => src}/public/js/lib/libde265.min.js (100%)
 rename web-service/server/{ => src}/public/js/lib/msgpack5.min.js (100%)

diff --git a/web-service/server/public/js/lib/Peer.js b/web-service/server/public/js/lib/Peer.js
deleted file mode 100644
index ff14903ac..000000000
--- a/web-service/server/public/js/lib/Peer.js
+++ /dev/null
@@ -1,243 +0,0 @@
-const msgpack = msgpack5()
-  , encode  = msgpack.encode
-  , decode  = msgpack.decode;
-
-const kConnecting = 1;
-const kConnected = 2;
-const kDisconnected = 3;
-
-// Generate a unique id for this webservice
-// let my_uuid = new Uint8Array(16);
-// my_uuid[0] = 44;
-// my_uuid = Buffer.from(my_uuid);
-
-const kMagic = 0x0009340053640912;
-const kVersion = 0;
-
-/**
- * Wrap a web socket with a MsgPack RCP protocol.
- * @param {websocket} ws Websocket object
- */
-function Peer(ws) {
-	this.sock = ws;
-	this.status = kConnecting;
-	this.id = null;
-	this.string_id = "";
-	this.bindings = {};
-	this.proxies = {};
-	this.events = {};
-	this.callbacks = {};
-	this.cbid = 0;
-
-	this.uri = "unknown";
-	this.name = "unknown";
-	this.master = false;
-
-	console.log(this.sock.send("message"));
-	
-	this.sock.send("message", (raw) => {
-		// console.log(raw)
-		let msg = decode(raw);
-		console.log("MSG", msg)
-		if (this.status == kConnecting) {
-			if (msg[1] != "__handshake__") {
-				console.log("Bad handshake");
-				this.close();
-			}
-		}
-		//console.log("MSG", msg);
-		if (msg[0] == 0) {
-			// Notification
-			if (msg.length == 3) {
-				this._dispatchNotification(msg[1], msg[2]);
-			// Call
-			} else {
-				this._dispatchCall(msg[2], msg[1], msg[3]);
-			}
-		} else if (msg[0] == 1) {
-			this._dispatchResponse(msg[1], msg[3]);
-		}
-	});
-
-	this.sock.on("close", () => {
-		this.status = kDisconnected;
-		this._notify("disconnect", this);
-	});
-
-	this.sock.on("error", () => {
-		console.error("Socket error");
-		this.sock.close();
-		this.status = kDisconnected;
-	});
-
-	this.bind("__handshake__", (magic, version, id) => {
-		if (magic == kMagic) {
-			console.log("Handshake received");
-			this.status = kConnected;
-			this.id = id.buffer;
-			this.string_id  = id.toString('hex');
-			this._notify("connect", this);
-		} else {
-			console.log("Magic does not match");
-			this.close();
-		}
-	});
-
-	this.send("__handshake__", kMagic, kVersion, /*[my_uuid]*/);
-}
-
-// Peer.uuid = my_uuid;
-
-/**
- * @private
- */
-Peer.prototype._dispatchNotification = function(name, args) {
-	if (this.bindings.hasOwnProperty(name)) {
-		//console.log("Notification for: ", name);
-		this.bindings[name].apply(this, args);
-	} else {
-		console.log("Missing handler for: ", name);
-	}
-}
-
-/**
- * @private
- */
-Peer.prototype._dispatchCall = function(name, id, args) {
-	if (this.bindings.hasOwnProperty(name)) {
-		//console.log("Call for:", name, id);
-
-		try {
-			let res = this.bindings[name].apply(this, args);
-			this.sock.send(encode([1,id,name,res]));
-		} catch(e) {
-			console.error("Could to dispatch or return call");
-			this.close();
-		}
-	} else if (this.proxies.hasOwnProperty(name)) {
-		//console.log("Proxy for:", name, id);
-		args.unshift((res) => {
-			try {
-				this.sock.send(encode([1,id,name,res]));
-			} catch(e) {
-				this.close();
-			}
-		});
-		this.proxies[name].apply(this, args);
-	} else {
-		console.log("Missing handler for: ", name);
-	}
-}
-
-/**
- * @private
- */
-Peer.prototype._dispatchResponse = function(id, res) {
-	if (this.callbacks.hasOwnProperty(id)) {
-		this.callbacks[id].call(this, res);
-		delete this.callbacks[id];
-	} else {
-		console.log("Missing callback");
-	}
-}
-
-/**
- * Register an RPC handler that will be called from a remote machine. Remotely
- * passed arguments are provided to the given function as normal arguments, and
- * if the function returns a value, it will be returned over the network also.
- * 
- * @param {string} name The name of the function
- * @param {function} f A function or lambda to be callable remotely
- */
-Peer.prototype.bind = function(name, f) {
-	if (this.bindings.hasOwnProperty(name)) {
-		//console.error("Duplicate bind to same procedure");
-		this.bindings[name] = f;
-	} else {
-		this.bindings[name] = f;
-	}
-}
-
-/**
- * Allow an RPC call to pass through to another machine with minimal local
- * processing.
- */
-Peer.prototype.proxy = function(name, f) {
-	if (this.proxies.hasOwnProperty(name)) {
-		//console.error("Duplicate proxy to same procedure");
-		this.proxies[name] = f;
-	} else {
-		this.proxies[name] = f;
-	}
-}
-
-/**
- * Call a procedure on a remote machine.
- * 
- * @param {string} name Name of the procedure
- * @param {function} cb Callback to receive return value as argument
- * @param {...} args Any number of arguments to also pass to remote procedure
- */
-Peer.prototype.rpc = function(name, cb, ...args) {
-	let id = this.cbid++;
-	this.callbacks[id] = cb;
-
-	try {
-		this.sock.send(encode([0, id, name, args]));
-	} catch(e) {
-		this.close();
-	}
-}
-
-Peer.prototype.sendB = function(name, args) {
-	try {
-		this.sock.send(encode([0, name, args]));
-	} catch(e) {
-		this.close();
-	}
-}
-
-/**
- * Call a remote procedure but with no return value expected.
- * 
- * @param {string} name Name of the procedure
- * @param {...} args Any number of arguments to also pass to remote procedure
- */
-Peer.prototype.send = function(name, ...args) {
-	try {
-		this.sock.send(encode([0, name, args]));
-	} catch(e) {
-		this.close();
-	}
-}
-
-Peer.prototype.close = function() {
-	this.sock.close();
-	this.status = kDisconnected;
-}
-
-/**
- * @private
- */
-Peer.prototype._notify = function(evt, ...args) {
-	if (this.events.hasOwnProperty(evt)) {
-		for (let i=0; i<this.events[evt].length; i++) {
-			let f = this.events[evt][i];
-			f.apply(this, args);
-		}
-	}
-}
-
-/**
- * Register a callback for socket events. Events include: 'connect',
- * 'disconnect' and 'error'.
- * 
- * @param {string} evt Event name
- * @param {function} f Callback on event
- */
-Peer.prototype.on = function(evt, f) {
-	if (!this.events.hasOwnProperty(evt)) {
-		this.events[evt] = [];
-	}
-	this.events[evt].push(f);
-}
\ No newline at end of file
diff --git a/web-service/server/src/index.js b/web-service/server/src/index.js
index f841ae1cb..33e1c8c1e 100644
--- a/web-service/server/src/index.js
+++ b/web-service/server/src/index.js
@@ -453,7 +453,7 @@ app.ws('/', (ws, req) => {
 	});
 
 	// Request from frames from a source
-	p.bind("get_stream", (uri, N, rate, pid, dest) => {
+	p.bind("get_stream", (uri, N, rate, /*pid,*/ dest) => {
 		let peer = uri_data[uri].peer;
 		console.log('PEER', peer);
 		if (peer) {
diff --git a/web-service/server/src/peer.js b/web-service/server/src/peer.js
index 75ffcff1d..692e884bc 100644
--- a/web-service/server/src/peer.js
+++ b/web-service/server/src/peer.js
@@ -33,8 +33,17 @@ function Peer(ws) {
 	this.name = "unknown";
 	this.master = false;
 
+	if(this.sock.on == undefined){
+		console.log(this.sock);
+		this.sock.onopen = () => {
+			this.sock.send(encode([1, "__handshake__"]))
+			console.log("piip")
+			this.sock.send('get_stream')
+			console.log("piippiip")
+		}
+	}
 	this.sock.on("message", (raw) => {
-		// console.log(raw)
+		console.log(raw)
 		let msg = decode(raw);
 		console.log("MSG", msg)
 		if (this.status == kConnecting) {
@@ -82,7 +91,8 @@ function Peer(ws) {
 	});
 
 	this.send("__handshake__", kMagic, kVersion, [my_uuid]);
-}
+}		
+
 
 Peer.uuid = my_uuid;
 
diff --git a/web-service/server/public/css/index.css b/web-service/server/src/public/css/index.css
similarity index 100%
rename from web-service/server/public/css/index.css
rename to web-service/server/src/public/css/index.css
diff --git a/web-service/server/public/index.html b/web-service/server/src/public/index.html
similarity index 89%
rename from web-service/server/public/index.html
rename to web-service/server/src/public/index.html
index 9d16873a7..6b688005d 100644
--- a/web-service/server/public/index.html
+++ b/web-service/server/src/public/index.html
@@ -11,5 +11,4 @@
     <script src="./js/lib/libde265.min.js"></script>
     <script src="./js/lib/msgpack5.min.js"></script>
     <script src="./js/lib/bundle.js"></script>
-    <script src="./js/index.js"></script>
 </html>
\ No newline at end of file
diff --git a/web-service/server/public/js/index.js b/web-service/server/src/public/js/index.js
similarity index 90%
rename from web-service/server/public/js/index.js
rename to web-service/server/src/public/js/index.js
index eb5e54580..ac8db6b3b 100644
--- a/web-service/server/public/js/index.js
+++ b/web-service/server/src/public/js/index.js
@@ -1,6 +1,6 @@
+const Peer = require('../../peer')
 
-
-const checkIfLoggedIn = async () => {
+checkIfLoggedIn = async () => {
 //     const token = window.localStorage.getItem('token')
 //     console.log(token)
 //     if(!token){
@@ -24,7 +24,7 @@ const checkIfLoggedIn = async () => {
  }
 
 //Redirects the user to google authentication
-const handleLogin = () => {
+handleLogin = () => {
     window.location.href="/google";
 }
 
@@ -34,14 +34,14 @@ let current_data = {};
 /**
  * Returns a list of available streams
  */
-const getAvailableStreams = async () => {
+getAvailableStreams = async () => {
     const streamsInJson = await fetch('http://localhost:8080/streams');
     const streams = await streamsInJson.json();
     console.log('AVAILABLE', streams)
     return streams;
 }
 
-const videoPlayer = () => {
+videoPlayer = () => {
     const containerDiv = document.getElementById('container')
     containerDiv.innerHTML = `<h1>Stream ${current_data.uri} is live right here!</h1><br><button onclick="renderThumbnails()">Go back</button><br>
     <canvas id="ftlab-stream-video" width="0" height="0"></canvas>`;
@@ -55,7 +55,7 @@ const videoPlayer = () => {
 /**
  * Creates thumbnail (image) for all available streams and adds them to div class='container'
  */
-const renderThumbnails = async () => {
+renderThumbnails = async () => {
     const thumbnails = await getAvailableStreams();
     console.log('THUMBNAILS', thumbnails)
     const containerDiv = document.getElementById('container')
@@ -96,7 +96,7 @@ const renderThumbnails = async () => {
 /**
  * Renders button that will redirect to google login
  */
-const renderLogin = () => {
+renderLogin = () => {
     const containerDiv = document.getElementById('container');
         containerDiv.innerHTML = 
         `<div id='Login'>
@@ -121,7 +121,7 @@ const renderLogin = () => {
 }
 
 //FOR DESKTOP
-const createCard = (url, viewers) => {
+createCard = (url, viewers) => {
     return `<div class='ftlab-card-component' >
                 <img src='${url}' class="thumbnail-img" alt="Hups" width="250px"></img>
                 <p>Viewers: ${viewers}</p>
@@ -129,12 +129,14 @@ const createCard = (url, viewers) => {
             </div>`
 }
 
-const connectToStream = () => {
+connectToStream = () => {
     const ws = new WebSocket('ws://localhost:8080/');
+    current_data.frames = 10;
     let p = new Peer(ws);
-    p.send('message', ([0,'__handshake__']));
+    console.log("still working")
+    p.send("get_stream", (current_data.uri, current_data.frames, 0, current_data.uri));
+    console.log("still working")
 
-    current_data.frames = 10;
     //setTimeout 1s, ask for the amount of frames user has selected
 }
 
diff --git a/web-service/server/public/js/lib/bundle.js b/web-service/server/src/public/js/lib/bundle.js
similarity index 96%
rename from web-service/server/public/js/lib/bundle.js
rename to web-service/server/src/public/js/lib/bundle.js
index bf76f475f..dc9c6a287 100644
--- a/web-service/server/public/js/lib/bundle.js
+++ b/web-service/server/src/public/js/lib/bundle.js
@@ -383,7 +383,7 @@ BufferList.prototype._match = function(offset, search) {
 
 module.exports = BufferList
 
-},{"readable-stream":18,"safe-buffer":19,"util":38}],2:[function(require,module,exports){
+},{"readable-stream":18,"safe-buffer":19,"util":39}],2:[function(require,module,exports){
 (function (Buffer){
 // Copyright Joyent, Inc. and other Node contributors.
 //
@@ -494,7 +494,7 @@ function objectToString(o) {
 }
 
 }).call(this,{"isBuffer":require("../../../../../../../../../../../usr/lib/node_modules/browserify/node_modules/is-buffer/index.js")})
-},{"../../../../../../../../../../../usr/lib/node_modules/browserify/node_modules/is-buffer/index.js":32}],3:[function(require,module,exports){
+},{"../../../../../../../../../../../usr/lib/node_modules/browserify/node_modules/is-buffer/index.js":33}],3:[function(require,module,exports){
 if (typeof Object.create === 'function') {
   // implementation from standard node.js 'util' module
   module.exports = function inherits(ctor, superCtor) {
@@ -613,7 +613,7 @@ function msgpack (options) {
 
 module.exports = msgpack
 
-},{"./lib/decoder":6,"./lib/encoder":7,"./lib/streams":8,"assert":23,"bl":1,"safe-buffer":19}],6:[function(require,module,exports){
+},{"./lib/decoder":6,"./lib/encoder":7,"./lib/streams":8,"assert":24,"bl":1,"safe-buffer":19}],6:[function(require,module,exports){
 'use strict'
 
 var bl = require('bl')
@@ -1051,7 +1051,7 @@ module.exports = function buildDecode (decodingTypes) {
 
 module.exports.IncompleteBufferError = IncompleteBufferError
 
-},{"bl":1,"util":38}],7:[function(require,module,exports){
+},{"bl":1,"util":39}],7:[function(require,module,exports){
 'use strict'
 
 var Buffer = require('safe-buffer').Buffer
@@ -1537,7 +1537,7 @@ function nextTick(fn, arg1, arg2, arg3) {
 
 
 }).call(this,require('_process'))
-},{"_process":34}],10:[function(require,module,exports){
+},{"_process":35}],10:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -2739,7 +2739,7 @@ function indexOf(xs, x) {
   return -1;
 }
 }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./_stream_duplex":10,"./internal/streams/BufferList":15,"./internal/streams/destroy":16,"./internal/streams/stream":17,"_process":34,"core-util-is":2,"events":30,"inherits":3,"isarray":4,"process-nextick-args":9,"safe-buffer":19,"string_decoder/":20,"util":28}],13:[function(require,module,exports){
+},{"./_stream_duplex":10,"./internal/streams/BufferList":15,"./internal/streams/destroy":16,"./internal/streams/stream":17,"_process":35,"core-util-is":2,"events":31,"inherits":3,"isarray":4,"process-nextick-args":9,"safe-buffer":19,"string_decoder/":20,"util":29}],13:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -3644,7 +3644,7 @@ Writable.prototype._destroy = function (err, cb) {
   cb(err);
 };
 }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate)
-},{"./_stream_duplex":10,"./internal/streams/destroy":16,"./internal/streams/stream":17,"_process":34,"core-util-is":2,"inherits":3,"process-nextick-args":9,"safe-buffer":19,"timers":35,"util-deprecate":21}],15:[function(require,module,exports){
+},{"./_stream_duplex":10,"./internal/streams/destroy":16,"./internal/streams/stream":17,"_process":35,"core-util-is":2,"inherits":3,"process-nextick-args":9,"safe-buffer":19,"timers":36,"util-deprecate":21}],15:[function(require,module,exports){
 'use strict';
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
@@ -3724,7 +3724,7 @@ if (util && util.inspect && util.inspect.custom) {
     return this.constructor.name + ' ' + obj;
   };
 }
-},{"safe-buffer":19,"util":28}],16:[function(require,module,exports){
+},{"safe-buffer":19,"util":29}],16:[function(require,module,exports){
 'use strict';
 
 /*<replacement>*/
@@ -3802,7 +3802,7 @@ module.exports = {
 },{"process-nextick-args":9}],17:[function(require,module,exports){
 module.exports = require('events').EventEmitter;
 
-},{"events":30}],18:[function(require,module,exports){
+},{"events":31}],18:[function(require,module,exports){
 exports = module.exports = require('./lib/_stream_readable.js');
 exports.Stream = exports;
 exports.Readable = exports;
@@ -3875,7 +3875,7 @@ SafeBuffer.allocUnsafeSlow = function (size) {
   return buffer.SlowBuffer(size)
 }
 
-},{"buffer":29}],20:[function(require,module,exports){
+},{"buffer":30}],20:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -4280,8 +4280,17 @@ function Peer(ws) {
 	this.name = "unknown";
 	this.master = false;
 
+	if(this.sock.on == undefined){
+		console.log(this.sock);
+		this.sock.onopen = () => {
+			this.sock.send(encode([1, "__handshake__"]))
+			console.log("piip")
+			this.sock.send('get_stream')
+			console.log("piippiip")
+		}
+	}
 	this.sock.on("message", (raw) => {
-		// console.log(raw)
+		console.log(raw)
 		let msg = decode(raw);
 		console.log("MSG", msg)
 		if (this.status == kConnecting) {
@@ -4329,7 +4338,8 @@ function Peer(ws) {
 	});
 
 	this.send("__handshake__", kMagic, kVersion, [my_uuid]);
-}
+}		
+
 
 Peer.uuid = my_uuid;
 
@@ -4490,7 +4500,162 @@ Peer.prototype.on = function(evt, f) {
 module.exports = Peer;
 
 }).call(this,require("buffer").Buffer)
-},{"buffer":29,"msgpack5":5}],23:[function(require,module,exports){
+},{"buffer":30,"msgpack5":5}],23:[function(require,module,exports){
+const Peer = require('../../peer')
+
+checkIfLoggedIn = async () => {
+//     const token = window.localStorage.getItem('token')
+//     console.log(token)
+//     if(!token){
+//         console.log("You need to login")
+//         renderLogin()
+//     }else{
+
+//         //Check if the token is valid
+//         const response = await fetch('http://localhost:8080/auth/validation', {
+//             method: 'POST',
+//             headers: {'Authorization': token}
+//         })
+//         console.log('RESPONSE', response)
+        
+//         //Token is valid, show available streams
+//         if(response.status === 200){
+//             console.log("SUCCESS")
+           renderThumbnails()
+//         }
+//     }
+ }
+
+//Redirects the user to google authentication
+handleLogin = () => {
+    window.location.href="/google";
+}
+
+let current_data = {}; 
+
+
+/**
+ * Returns a list of available streams
+ */
+getAvailableStreams = async () => {
+    const streamsInJson = await fetch('http://localhost:8080/streams');
+    const streams = await streamsInJson.json();
+    console.log('AVAILABLE', streams)
+    return streams;
+}
+
+videoPlayer = () => {
+    const containerDiv = document.getElementById('container')
+    containerDiv.innerHTML = `<h1>Stream ${current_data.uri} is live right here!</h1><br><button onclick="renderThumbnails()">Go back</button><br>
+    <canvas id="ftlab-stream-video" width="0" height="0"></canvas>`;
+    containerDiv.innerHTML += '<br>'
+    containerDiv.innerHTML += ''
+    let decoder = new libde265.Decoder();
+    console.log(decoder)
+}
+
+
+/**
+ * Creates thumbnail (image) for all available streams and adds them to div class='container'
+ */
+renderThumbnails = async () => {
+    const thumbnails = await getAvailableStreams();
+    console.log('THUMBNAILS', thumbnails)
+    const containerDiv = document.getElementById('container')
+    containerDiv.innerHTML = '';
+    console.log(containerDiv)
+    for(var i=0; i<thumbnails.length; i++){
+        const encodedURI = encodeURIComponent(thumbnails[i])
+        current_data.uri = encodedURI
+        console.log("THUMBNAIL[i]", thumbnails[i])
+        try{
+            const someData = await fetch(`http://localhost:8080/stream/rgb?uri=${encodedURI}`)
+            console.log('SOME DATA', someData)
+            if(!someData.ok){
+                throw new Error('Image not found')
+            }
+            const myBlob = await someData.blob();
+            console.log('BLOB', myBlob)
+            const objectURL = URL.createObjectURL(myBlob);
+            // containerDiv.innerHTML += createCard()
+            containerDiv.innerHTML += createCard(objectURL, i+4)
+        }catch(err){
+            console.log("Couldn't create thumbnail");
+            console.log(err) 
+        }
+    }
+}
+
+
+// //FOR LAPTOP
+// const renderThumbnails = async () => {
+//     const containerDiv = document.getElementById('container')
+//     containerDiv.innerHTML = '';
+//     for(var i=0; i<2; i++){
+//             containerDiv.innerHTML += createCard()
+//     }
+// }
+
+/**
+ * Renders button that will redirect to google login
+ */
+renderLogin = () => {
+    const containerDiv = document.getElementById('container');
+        containerDiv.innerHTML = 
+        `<div id='Login'>
+            <h2>Welcome to Future Technology Lab</h2>
+            <h3>Please login!</h3>
+            <a className="button" onClick="handleLogin()">
+                <div>
+                    <span class="svgIcon t-popup-svg">
+                        <svg class="svgIcon-use" width="25" height="37" viewBox="0 0 25 25">
+                            <g fill="none" fill-rule="evenodd">
+                            <path d="M20.66 12.693c0-.603-.054-1.182-.155-1.738H12.5v3.287h4.575a3.91 3.91 0 0 1-1.697 2.566v2.133h2.747c1.608-1.48 2.535-3.65 2.535-6.24z" fill="#4285F4"/>
+                            <path d="M12.5 21c2.295 0 4.22-.76 5.625-2.06l-2.747-2.132c-.76.51-1.734.81-2.878.81-2.214 0-4.088-1.494-4.756-3.503h-2.84v2.202A8.498 8.498 0 0 0 12.5 21z" fill="#34A853"/>
+                            <path d="M7.744 14.115c-.17-.51-.267-1.055-.267-1.615s.097-1.105.267-1.615V8.683h-2.84A8.488 8.488 0 0 0 4 12.5c0 1.372.328 2.67.904 3.817l2.84-2.202z" fill="#FBBC05"/>
+                            <path d="M12.5 7.38c1.248 0 2.368.43 3.25 1.272l2.437-2.438C16.715 4.842 14.79 4 12.5 4a8.497 8.497 0 0 0-7.596 4.683l2.84 2.202c.668-2.01 2.542-3.504 4.756-3.504z" fill="#EA4335"/>
+                            </g>
+                        </svg>
+                    </span>
+                    <span class="button-label">Sign in with Google</span>
+                </div>
+            </a>
+        </div>`
+}
+
+//FOR DESKTOP
+createCard = (url, viewers) => {
+    return `<div class='ftlab-card-component' >
+                <img src='${url}' class="thumbnail-img" alt="Hups" width="250px"></img>
+                <p>Viewers: ${viewers}</p>
+                <button onclick="videoPlayer()">button</button>
+            </div>`
+}
+
+connectToStream = () => {
+    const ws = new WebSocket('ws://localhost:8080/');
+    current_data.frames = 10;
+    let p = new Peer(ws);
+    console.log("still working")
+    p.send("get_stream", (current_data.uri, current_data.frames, 0, current_data.uri));
+    console.log("still working")
+
+    //setTimeout 1s, ask for the amount of frames user has selected
+}
+
+//FOR LAPTOP
+// const createCard = () => {
+//     return `<div class='ftlab-card-component'>
+//                 <img src='https://via.placeholder.com/250x150' class="thumbnail-img" width="250px" alt="Hups"></img>
+//                 <p>Viewers: yes</p>
+//                 <button onclick="window.location.href='/stream?uri'">button</button>
+//             </div>`
+// }
+
+const cardLogic = () => {
+    const cards = document.getElementsByClassName('ftlab-card-component');
+}
+},{"../../peer":22}],24:[function(require,module,exports){
 (function (global){
 'use strict';
 
@@ -5000,16 +5165,16 @@ var objectKeys = Object.keys || function (obj) {
 };
 
 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"object-assign":33,"util/":26}],24:[function(require,module,exports){
+},{"object-assign":34,"util/":27}],25:[function(require,module,exports){
 arguments[4][3][0].apply(exports,arguments)
-},{"dup":3}],25:[function(require,module,exports){
+},{"dup":3}],26:[function(require,module,exports){
 module.exports = function isBuffer(arg) {
   return arg && typeof arg === 'object'
     && typeof arg.copy === 'function'
     && typeof arg.fill === 'function'
     && typeof arg.readUInt8 === 'function';
 }
-},{}],26:[function(require,module,exports){
+},{}],27:[function(require,module,exports){
 (function (process,global){
 // Copyright Joyent, Inc. and other Node contributors.
 //
@@ -5599,7 +5764,7 @@ function hasOwnProperty(obj, prop) {
 }
 
 }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./support/isBuffer":25,"_process":34,"inherits":24}],27:[function(require,module,exports){
+},{"./support/isBuffer":26,"_process":35,"inherits":25}],28:[function(require,module,exports){
 'use strict'
 
 exports.byteLength = byteLength
@@ -5753,9 +5918,9 @@ function fromByteArray (uint8) {
   return parts.join('')
 }
 
-},{}],28:[function(require,module,exports){
-
 },{}],29:[function(require,module,exports){
+
+},{}],30:[function(require,module,exports){
 (function (Buffer){
 /*!
  * The buffer module from node.js, for the browser.
@@ -7558,7 +7723,7 @@ var hexSliceLookupTable = (function () {
 })()
 
 }).call(this,require("buffer").Buffer)
-},{"base64-js":27,"buffer":29,"ieee754":31}],30:[function(require,module,exports){
+},{"base64-js":28,"buffer":30,"ieee754":32}],31:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -8083,7 +8248,7 @@ function functionBindPolyfill(context) {
   };
 }
 
-},{}],31:[function(require,module,exports){
+},{}],32:[function(require,module,exports){
 exports.read = function (buffer, offset, isLE, mLen, nBytes) {
   var e, m
   var eLen = (nBytes * 8) - mLen - 1
@@ -8169,7 +8334,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
   buffer[offset + i - d] |= s * 128
 }
 
-},{}],32:[function(require,module,exports){
+},{}],33:[function(require,module,exports){
 /*!
  * Determine if an object is a Buffer
  *
@@ -8192,7 +8357,7 @@ function isSlowBuffer (obj) {
   return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
 }
 
-},{}],33:[function(require,module,exports){
+},{}],34:[function(require,module,exports){
 /*
 object-assign
 (c) Sindre Sorhus
@@ -8284,7 +8449,7 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) {
 	return to;
 };
 
-},{}],34:[function(require,module,exports){
+},{}],35:[function(require,module,exports){
 // shim for using process in browser
 var process = module.exports = {};
 
@@ -8470,7 +8635,7 @@ process.chdir = function (dir) {
 };
 process.umask = function() { return 0; };
 
-},{}],35:[function(require,module,exports){
+},{}],36:[function(require,module,exports){
 (function (setImmediate,clearImmediate){
 var nextTick = require('process/browser.js').nextTick;
 var apply = Function.prototype.apply;
@@ -8549,10 +8714,10 @@ exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate :
   delete immediateIds[id];
 };
 }).call(this,require("timers").setImmediate,require("timers").clearImmediate)
-},{"process/browser.js":34,"timers":35}],36:[function(require,module,exports){
+},{"process/browser.js":35,"timers":36}],37:[function(require,module,exports){
 arguments[4][3][0].apply(exports,arguments)
-},{"dup":3}],37:[function(require,module,exports){
-arguments[4][25][0].apply(exports,arguments)
-},{"dup":25}],38:[function(require,module,exports){
+},{"dup":3}],38:[function(require,module,exports){
 arguments[4][26][0].apply(exports,arguments)
-},{"./support/isBuffer":37,"_process":34,"dup":26,"inherits":36}]},{},[22]);
+},{"dup":26}],39:[function(require,module,exports){
+arguments[4][27][0].apply(exports,arguments)
+},{"./support/isBuffer":38,"_process":35,"dup":27,"inherits":37}]},{},[23]);
diff --git a/web-service/server/public/js/lib/libde265.min.js b/web-service/server/src/public/js/lib/libde265.min.js
similarity index 100%
rename from web-service/server/public/js/lib/libde265.min.js
rename to web-service/server/src/public/js/lib/libde265.min.js
diff --git a/web-service/server/public/js/lib/msgpack5.min.js b/web-service/server/src/public/js/lib/msgpack5.min.js
similarity index 100%
rename from web-service/server/public/js/lib/msgpack5.min.js
rename to web-service/server/src/public/js/lib/msgpack5.min.js
-- 
GitLab