From 9c7521a36f67b3a69ac40f8a55e66638ed96bf04 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Tue, 29 Oct 2019 18:29:57 -0400
Subject: Client Side Namespace

---
 src/client/views/webcam/DashWebRTCVideo.tsx | 339 ++++++++++++++++++++++++++++
 1 file changed, 339 insertions(+)
 create mode 100644 src/client/views/webcam/DashWebRTCVideo.tsx

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
new file mode 100644
index 000000000..db9c922fc
--- /dev/null
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -0,0 +1,339 @@
+import { observer } from "mobx-react";
+import React = require("react");
+import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView";
+import { FieldViewProps, FieldView } from "../nodes/FieldView";
+import { observable } from "mobx";
+import { DocumentDecorations } from "../DocumentDecorations";
+import { InkingControl } from "../InkingControl";
+import "../../views/nodes/WebBox.scss";
+import "./DashWebRTC.scss";
+import adapter from 'webrtc-adapter';
+import { DashWebRTC } from "./DashWebRTC";
+
+
+
+
+const mediaStreamConstraints = {
+    video: true,
+};
+
+const offerOptions = {
+    offerToReceiveVideo: 1,
+};
+
+
+@observer
+export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentViewProps & FieldViewProps> {
+
+    @observable private localVideoEl: HTMLVideoElement | undefined;
+    @observable private peerVideoEl: HTMLVideoElement | undefined;
+    @observable private localStream: MediaStream | undefined;
+    @observable private startTime: any = null;
+    @observable private remoteStream: MediaStream | undefined;
+    @observable private localPeerConnection: any;
+    @observable private remotePeerConnection: any;
+    private callButton: HTMLButtonElement | undefined;
+    private startButton: HTMLButtonElement | undefined;
+    private hangupButton: HTMLButtonElement | undefined;
+
+    componentDidMount() {
+        DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
+    }
+
+
+    // componentDidMount() {
+    //     this.callButton!.disabled = true;
+    //     this.hangupButton!.disabled = true;
+    //     // navigator.mediaDevices.getUserMedia(mediaStreamConstraints).then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError);
+    //     this.localVideoEl!.addEventListener('loadedmetadata', this.logVideoLoaded);
+    //     this.peerVideoEl!.addEventListener('loadedmetadata', this.logVideoLoaded);
+    //     this.peerVideoEl!.addEventListener('onresize', this.logResizedVideo);
+    // }
+
+
+    // gotLocalMediaStream = (mediaStream: MediaStream) => {
+    //     this.localStream = mediaStream;
+    //     if (this.localVideoEl) {
+    //         this.localVideoEl.srcObject = mediaStream;
+    //     }
+    //     this.trace('Received local stream.');
+    //     this.callButton!.disabled = false;
+
+    // }
+
+    // gotRemoteMediaStream = (event: MediaStreamEvent) => {
+    //     let mediaStream = event.stream;
+    //     this.peerVideoEl!.srcObject = mediaStream;
+    //     this.remoteStream = mediaStream!;
+
+    // }
+
+    // handleLocalMediaStreamError = (error: string) => {
+    //     //console.log("navigator.getUserMedia error: ", error);
+    //     this.trace(`navigator.getUserMedia error: ${error.toString()}.`);
+
+    // }
+
+    // logVideoLoaded = (event: any) => {
+    //     let video = event.target;
+    //     this.trace(`${video.id} videoWidth: ${video.videoWidth}px, ` +
+    //         `videoHeight: ${video.videoHeight}px.`);
+    // }
+
+    // logResizedVideo = (event: any) => {
+    //     this.logVideoLoaded(event);
+
+    //     if (this.startTime) {
+    //         let elapsedTime = window.performance.now() - this.startTime;
+    //         this.startTime = null;
+    //         this.trace(`Setup time: ${elapsedTime.toFixed(3)}ms.`);
+    //     }
+
+    // }
+
+    // handleConnection = (event: any) => {
+    //     let peerConnection = event.target;
+    //     let iceCandidate = event.candidate;
+
+    //     if (iceCandidate) {
+    //         let newIceCandidate: RTCIceCandidate = new RTCIceCandidate(iceCandidate);
+    //         let otherPeer: any = this.getOtherPeer(peerConnection);
+
+    //         otherPeer.addIceCandidate(newIceCandidate).then(() => {
+    //             this.handleConnectionSuccess(peerConnection);
+    //         }).catch((error: any) => {
+    //             this.handleConnectionFailure(peerConnection, error);
+    //         });
+
+    //         this.trace(`${this.getPeerName(peerConnection)} ICE candidate:\n` +
+    //             `${event.candidate.candidate}.`);
+
+    //     }
+    // }
+
+    // // Logs that the connection succeeded.
+    // handleConnectionSuccess = (peerConnection: any) => {
+    //     this.trace(`${this.getPeerName(peerConnection)} addIceCandidate success.`);
+    // }
+
+    // handleConnectionFailure = (peerConnection: any, error: any) => {
+    //     this.trace(`${this.getPeerName(peerConnection)} failed to add ICE Candidate:\n` +
+    //         `${error.toString()}.`);
+    // }
+
+    // // Logs changes to the connection state.
+    // handleConnectionChange = (event: any) => {
+    //     let peerConnection = event.target;
+    //     console.log('ICE state change event: ', event);
+    //     this.trace(`${this.getPeerName(peerConnection)} ICE state: ` +
+    //         `${peerConnection.iceConnectionState}.`);
+    // }
+
+    // // Logs error when setting session description fails.
+    // setSessionDescriptionError = (error: any) => {
+    //     this.trace(`Failed to create session description: ${error.toString()}.`);
+    // }
+
+    // // Logs success when setting session description.
+    // setDescriptionSuccess = (peerConnection: any, functionName: any) => {
+    //     let peerName = this.getPeerName(peerConnection);
+    //     this.trace(`${peerName} ${functionName} complete.`);
+    // }
+
+
+    // // Logs success when localDescription is set.
+    // setLocalDescriptionSuccess = (peerConnection: any) => {
+    //     this.setDescriptionSuccess(peerConnection, 'setLocalDescription');
+    // }
+
+    // // Logs success when remoteDescription is set.
+    // setRemoteDescriptionSuccess = (peerConnection: any) => {
+    //     this.setDescriptionSuccess(peerConnection, 'setRemoteDescription');
+    // }
+
+    // createdOffer = (description: any) => {
+    //     this.trace(`Offer from localPeerConnection:\n${description.sdp}`);
+    //     this.trace('localPeerConnection setLocalDescription start.');
+
+    //     this.localPeerConnection.setLocalDescription(description).then(() => {
+    //         this.setLocalDescriptionSuccess(this.localPeerConnection);
+    //     }).catch(this.setSessionDescriptionError);
+
+
+    //     this.trace('remotePeerConnection setRemoteDescription start.');
+    //     this.remotePeerConnection.setRemoteDescription(description)
+    //         .then(() => {
+    //             this.setRemoteDescriptionSuccess(this.remotePeerConnection);
+    //         }).catch(this.setSessionDescriptionError);
+
+    //     this.trace('remotePeerConnection createAnswer start.');
+    //     this.remotePeerConnection.createAnswer()
+    //         .then(this.createdAnswer)
+    //         .catch(this.setSessionDescriptionError);
+
+    // }
+
+    // createdAnswer = (description: any) => {
+    //     this.trace(`Answer from remotePeerConnection:\n${description.sdp}.`);
+
+    //     this.trace('remotePeerConnection setLocalDescription start.');
+    //     this.remotePeerConnection.setLocalDescription(description)
+    //         .then(() => {
+    //             this.setLocalDescriptionSuccess(this.remotePeerConnection);
+    //         }).catch(this.setSessionDescriptionError);
+
+    //     this.trace('localPeerConnection setRemoteDescription start.');
+    //     this.localPeerConnection.setRemoteDescription(description)
+    //         .then(() => {
+    //             this.setRemoteDescriptionSuccess(this.localPeerConnection);
+    //         }).catch(this.setSessionDescriptionError);
+    // }
+
+
+    // startAction = () => {
+    //     this.startButton!.disabled = true;
+    //     navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
+    //         .then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError);
+    //     this.trace('Requesting local stream.');
+    // }
+
+
+    // // Handles call button action: creates peer connection.
+    // callAction = () => {
+    //     this.callButton!.disabled = true;
+    //     this.hangupButton!.disabled = false;
+
+    //     this.trace('Starting call.');
+    //     this.startTime = window.performance.now();
+
+    //     // Get local media stream tracks.
+    //     const videoTracks = this.localStream!.getVideoTracks();
+    //     const audioTracks = this.localStream!.getAudioTracks();
+    //     if (videoTracks.length > 0) {
+    //         this.trace(`Using video device: ${videoTracks[0].label}.`);
+    //     }
+    //     if (audioTracks.length > 0) {
+    //         this.trace(`Using audio device: ${audioTracks[0].label}.`);
+    //     }
+
+    //     let servers: RTCConfiguration | undefined = undefined;  // Allows for RTC server configuration.
+
+    //     // Create peer connections and add behavior.
+    //     this.localPeerConnection = new RTCPeerConnection(servers);
+    //     this.trace('Created local peer connection object localPeerConnection.');
+
+    //     this.localPeerConnection.addEventListener('icecandidate', this.handleConnection);
+    //     this.localPeerConnection.addEventListener(
+    //         'iceconnectionstatechange', this.handleConnectionChange);
+
+    //     this.remotePeerConnection = new RTCPeerConnection(servers);
+    //     this.trace('Created remote peer connection object remotePeerConnection.');
+
+    //     this.remotePeerConnection.addEventListener('icecandidate', this.handleConnection);
+    //     this.remotePeerConnection.addEventListener(
+    //         'iceconnectionstatechange', this.handleConnectionChange);
+    //     this.remotePeerConnection.addEventListener('addstream', this.gotRemoteMediaStream);
+
+    //     // Add local stream to connection and create offer to connect.
+    //     this.localPeerConnection.addStream(this.localStream);
+    //     this.trace('Added local stream to localPeerConnection.');
+
+    //     this.trace('localPeerConnection createOffer start.');
+    //     this.localPeerConnection.createOffer(offerOptions)
+    //         .then(this.createdOffer).catch(this.setSessionDescriptionError);
+    // }
+
+
+    // // Handles hangup action: ends up call, closes connections and resets peers.
+    // hangupAction = () => {
+    //     this.localPeerConnection.close();
+    //     this.remotePeerConnection.close();
+    //     this.localPeerConnection = null;
+    //     this.remotePeerConnection = null;
+    //     this.hangupButton!.disabled = true;
+    //     this.callButton!.disabled = false;
+    //     this.trace('Ending call.');
+    // }
+
+    // // Gets the "other" peer connection.
+    // getOtherPeer = (peerConnection: any) => {
+    //     return (peerConnection === this.localPeerConnection) ?
+    //         this.remotePeerConnection : this.localPeerConnection;
+    // }
+
+    // // Gets the name of a certain peer connection.
+    // getPeerName = (peerConnection: any) => {
+    //     return (peerConnection === this.localPeerConnection) ?
+    //         'localPeerConnection' : 'remotePeerConnection';
+    // }
+
+    // // Logs an action (text) and the time when it happened on the console.
+    // trace = (text: string) => {
+    //     text = text.trim();
+    //     const now = (window.performance.now() / 1000).toFixed(3);
+
+    //     console.log(now, text);
+    // }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    public static LayoutString() { return FieldView.LayoutString(DashWebRTCVideo); }
+
+
+    _ignore = 0;
+    onPreWheel = (e: React.WheelEvent) => {
+        this._ignore = e.timeStamp;
+    }
+    onPrePointer = (e: React.PointerEvent) => {
+        this._ignore = e.timeStamp;
+    }
+    onPostPointer = (e: React.PointerEvent) => {
+        if (this._ignore !== e.timeStamp) {
+            e.stopPropagation();
+        }
+    }
+    onPostWheel = (e: React.WheelEvent) => {
+        if (this._ignore !== e.timeStamp) {
+            e.stopPropagation();
+        }
+    }
+
+
+
+    render() {
+        let content =
+            <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+                <video id="localVideo" autoPlay playsInline ref={(e) => this.localVideoEl = e!}></video>
+                <video id="remoteVideo" autoPlay playsInline ref={(e) => this.peerVideoEl = e!}></video>
+                {/* <button id="startButton" ref={(e) => this.startButton = e!} onClick={this.startAction}>Start</button>
+                <button id="callButton" ref={(e) => this.callButton = e!} onClick={this.callAction}>Call</button>
+                <button id="hangupButton" ref={(e) => this.hangupButton = e!} onClick={this.hangupAction}>Hang Up</button> */}
+            </div>;
+
+        let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
+        let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
+
+
+        return (
+            <>
+                <div className={classname}  >
+                    {content}
+                </div>
+                {!frozen ? (null) : <div className="webBox-overlay" onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} />}
+            </>);
+    }
+
+
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From d97091421468238d32edf55c240bfb3b021e9e05 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Tue, 29 Oct 2019 18:52:26 -0400
Subject: couple fixes

---
 src/client/views/nodes/DocumentContentsView.tsx | 4 ++--
 src/client/views/webcam/DashWebRTCVideo.tsx     | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index f1678d4f9..ee58e4152 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -34,7 +34,7 @@ import { StrCast, NumCast } from "../../../new_fields/Types";
 import { List } from "../../../new_fields/List";
 import { fromPromise } from "mobx-utils";
 import { DashWebCam } from "../../views/webcam/DashWebCam";
-import { DashWebRTC } from "../webcam/DashWebRTC";
+import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo";
 
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
@@ -107,7 +107,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
         if (!this.layout && this.props.layoutKey !== "overlayLayout") return (null);
         return <ObserverJsxParser
             blacklistedAttrs={[]}
-            components={{ FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, DragBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox, PresElementBox, DashWebCam, DashWebRTC }}
+            components={{ FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, DragBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox, PresElementBox, DashWebCam, DashWebRTCVideo }}
             bindings={this.CreateBindings()}
             jsx={this.finalLayout}
             showWarnings={true}
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index db9c922fc..5bb7cef6f 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -8,7 +8,7 @@ import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
 import "./DashWebRTC.scss";
 import adapter from 'webrtc-adapter';
-import { DashWebRTC } from "./DashWebRTC";
+//import { DashWebRTC } from "./DashWebRTC";
 
 
 
@@ -37,7 +37,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private hangupButton: HTMLButtonElement | undefined;
 
     componentDidMount() {
-        DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
+        //DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
     }
 
 
-- 
cgit v1.2.3-70-g09d2


From b2777f92b50f926357ad9b595c7907368b996fbd Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Sun, 3 Nov 2019 14:38:44 -0500
Subject: Moved code into init

---
 src/client/views/webcam/DashWebRTC.ts       | 145 +++++++++++++++-------------
 src/client/views/webcam/DashWebRTCVideo.tsx |   5 +-
 2 files changed, 83 insertions(+), 67 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
index 4472f5ba5..801fd782d 100644
--- a/src/client/views/webcam/DashWebRTC.ts
+++ b/src/client/views/webcam/DashWebRTC.ts
@@ -12,6 +12,9 @@ export namespace DashWebRTC {
     let pc: any;
     let remoteStream: MediaStream | undefined;
     let turnReady;
+    let localVideo: HTMLVideoElement;
+    let remoteVideo: HTMLVideoElement;
+
 
     let pcConfig = {
         'iceServers': [{
@@ -25,42 +28,92 @@ export namespace DashWebRTC {
         offerToReceiveVideo: true
     };
 
+    export function init() {
+        let room = 'test';
 
-    let room = 'test';
+        if (room !== '') {
+            DocServer._socket.emit('create or join', room);
+            console.log('Attempted to create or  join room', room);
 
-    //let socket = io.connect();
+        }
 
-    if (room !== '') {
-        DocServer._socket.emit('create or join', room);
-        console.log('Attempted to create or  join room', room);
+        DocServer._socket.on('created', function (room: string) {
+            console.log('Created room ' + room);
+            isInitiator = true;
+        });
 
-    }
+        DocServer._socket.on('full', function (room: string) {
+            console.log('Room ' + room + ' is full');
+        });
 
-    DocServer._socket.on('created', function (room: string) {
-        console.log('Created room ' + room);
-        isInitiator = true;
-    });
+        DocServer._socket.on('join', function (room: string) {
+            console.log('Another peer made a request to join room ' + room);
+            console.log('This peer is the initiator of room ' + room + '!');
+            isChannelReady = true;
+        });
 
-    DocServer._socket.on('full', function (room: string) {
-        console.log('Room ' + room + ' is full');
-    });
 
-    DocServer._socket.on('join', function (room: string) {
-        console.log('Another peer made a request to join room ' + room);
-        console.log('This peer is the initiator of room ' + room + '!');
-        isChannelReady = true;
-    });
+        DocServer._socket.on('joined', function (room: string) {
+            console.log('joined: ' + room);
+            isChannelReady = true;
+        });
 
 
-    DocServer._socket.on('joined', function (room: string) {
-        console.log('joined: ' + room);
-        isChannelReady = true;
-    });
+        DocServer._socket.on('log', function (array: any) {
+            console.log.apply(console, array);
+        });
+
+        // This client receives a message
+        DocServer._socket.on('message', function (message: any) {
+            console.log('Client received message:', message);
+            if (message === 'got user media') {
+                maybeStart();
+            } else if (message.type === 'offer') {
+                if (!isInitiator && !isStarted) {
+                    maybeStart();
+                }
+                pc.setRemoteDescription(new RTCSessionDescription(message));
+                doAnswer();
+            } else if (message.type === 'answer' && isStarted) {
+                pc.setRemoteDescription(new RTCSessionDescription(message));
+            } else if (message.type === 'candidate' && isStarted) {
+                var candidate = new RTCIceCandidate({
+                    sdpMLineIndex: message.label,
+                    candidate: message.candidate
+                });
+                pc.addIceCandidate(candidate);
+            } else if (message === 'bye' && isStarted) {
+                handleRemoteHangup();
+            }
+        });
+
+        navigator.mediaDevices.getUserMedia({
+            audio: false,
+            video: true
+        })
+            .then(gotStream)
+            .catch(function (e) {
+                alert('getUserMedia() error: ' + e.name);
+            });
+
+        //Trying this one out!!!
+        console.log('Getting user media with constraints', constraints);
+
+        if (location.hostname !== 'localhost') {
+            requestTurn(
+                'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
+            );
+        }
+
+
+    }
+
+
+
+
+    //let socket = io.connect();
 
 
-    DocServer._socket.on('log', function (array: any) {
-        console.log.apply(console, array);
-    });
 
 
     function sendMessage(message: any) {
@@ -69,46 +122,15 @@ export namespace DashWebRTC {
     }
 
 
-    // This client receives a message
-    DocServer._socket.on('message', function (message: any) {
-        console.log('Client received message:', message);
-        if (message === 'got user media') {
-            maybeStart();
-        } else if (message.type === 'offer') {
-            if (!isInitiator && !isStarted) {
-                maybeStart();
-            }
-            pc.setRemoteDescription(new RTCSessionDescription(message));
-            doAnswer();
-        } else if (message.type === 'answer' && isStarted) {
-            pc.setRemoteDescription(new RTCSessionDescription(message));
-        } else if (message.type === 'candidate' && isStarted) {
-            var candidate = new RTCIceCandidate({
-                sdpMLineIndex: message.label,
-                candidate: message.candidate
-            });
-            pc.addIceCandidate(candidate);
-        } else if (message === 'bye' && isStarted) {
-            handleRemoteHangup();
-        }
-    });
 
-    let localVideo: HTMLVideoElement;
-    let remoteVideo: HTMLVideoElement;
+
 
     export function setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
         localVideo = localVideo;
         remoteVideo = remoteVideo;
     }
 
-    navigator.mediaDevices.getUserMedia({
-        audio: false,
-        video: true
-    })
-        .then(gotStream)
-        .catch(function (e) {
-            alert('getUserMedia() error: ' + e.name);
-        });
+
 
 
     function gotStream(stream: any) {
@@ -127,14 +149,7 @@ export namespace DashWebRTC {
     };
 
 
-    //Trying this one out!!!
-    console.log('Getting user media with constraints', constraints);
 
-    if (location.hostname !== 'localhost') {
-        requestTurn(
-            'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
-        );
-    }
 
 
     function maybeStart() {
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 5bb7cef6f..dcaa87557 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -8,7 +8,7 @@ import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
 import "./DashWebRTC.scss";
 import adapter from 'webrtc-adapter';
-//import { DashWebRTC } from "./DashWebRTC";
+import { DashWebRTC } from "./DashWebRTC";
 
 
 
@@ -37,7 +37,8 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private hangupButton: HTMLButtonElement | undefined;
 
     componentDidMount() {
-        //DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
+        DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
+        DashWebRTC.init();
     }
 
 
-- 
cgit v1.2.3-70-g09d2


From 2cf3ed4cd22726fdbe7f587605457271482c3a28 Mon Sep 17 00:00:00 2001
From: andrewdkim <adkim414@gmail.com>
Date: Tue, 5 Nov 2019 18:31:52 -0500
Subject: add a prompt and figure out message why not sending

---
 src/client/views/webcam/DashWebRTC.ts       | 44 ++++++++---------------------
 src/client/views/webcam/DashWebRTCVideo.tsx | 16 ++++++++---
 src/server/index.ts                         |  4 +--
 3 files changed, 25 insertions(+), 39 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
index 801fd782d..bd0bd7f9a 100644
--- a/src/client/views/webcam/DashWebRTC.ts
+++ b/src/client/views/webcam/DashWebRTC.ts
@@ -1,7 +1,9 @@
 import { DocServer } from '../../DocServer';
 
 
-
+/**
+ * This namespace will have the code required to have functionality code for the usage of webRTC.
+ */
 export namespace DashWebRTC {
 
 
@@ -130,6 +132,14 @@ export namespace DashWebRTC {
         remoteVideo = remoteVideo;
     }
 
+    export function setLocalVideoObject(localVideoRef: HTMLVideoElement) {
+        localVideo = localVideoRef;
+    }
+
+    export function setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
+        remoteVideo = remoteVideoRef;
+    }
+
 
 
 
@@ -286,36 +296,4 @@ export namespace DashWebRTC {
     }
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 62efd9730..503b71569 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -21,7 +21,9 @@ const offerOptions = {
     offerToReceiveVideo: 1,
 };
 
-
+/**
+ * This models the component that will be rendered, that can be used as a doc that will reflect the video cams.
+ */
 @observer
 export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentViewProps & FieldViewProps> {
 
@@ -37,7 +39,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private hangupButton: HTMLButtonElement | undefined;
 
     componentDidMount() {
-        DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
+        // DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
         DashWebRTC.init();
     }
 
@@ -317,8 +319,14 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     render() {
         let content =
             <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
-                <video id="localVideo" autoPlay playsInline ref={(e) => this.localVideoEl = e!}></video>
-                <video id="remoteVideo" autoPlay playsInline ref={(e) => this.peerVideoEl = e!}></video>
+                <video id="localVideo" autoPlay playsInline ref={(e) => {
+                    this.localVideoEl = e!;
+                    DashWebRTC.setLocalVideoObject(e!);
+                }}></video>
+                <video id="remoteVideo" autoPlay playsInline ref={(e) => {
+                    this.peerVideoEl = e!;
+                    DashWebRTC.setRemoteVideoObject(e!);
+                }}></video>
                 {/* <button id="startButton" ref={(e) => this.startButton = e!} onClick={this.startAction}>Start</button>
                 <button id="callButton" ref={(e) => this.callButton = e!} onClick={this.callAction}>Call</button>
                 <button id="hangupButton" ref={(e) => this.hangupButton = e!} onClick={this.hangupAction}>Hang Up</button> */}
diff --git a/src/server/index.ts b/src/server/index.ts
index e33fd4b71..77f048a1e 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -983,8 +983,8 @@ function HandleYoutubeQuery([query, callback]: [YoutubeQueryInput, (result?: any
 }
 
 function HandleRoommateNotification(socket: Socket, message: RoomMessage) {
-    //socket.broadcast.emit('message', message);
-    server.sockets.in(message.room).emit('message', message.message);
+    socket.broadcast.emit('message', message);
+    //server.sockets.in(message.room).emit('message', message.message);
 
 }
 
-- 
cgit v1.2.3-70-g09d2


From 76bc6041ddbbda7ba4c1560199acc08324648e99 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <muhammedamoush@gmail.com>
Date: Wed, 6 Nov 2019 19:20:45 -0500
Subject: 2 person call done

---
 src/client/northstar/utils/Utils.ts         |  6 ++++++
 src/client/views/webcam/DashWebRTC.ts       | 26 +++++++++++++++-----------
 src/client/views/webcam/DashWebRTCVideo.tsx | 24 ++++++++++++++++++++----
 src/server/Message.ts                       |  2 +-
 4 files changed, 42 insertions(+), 16 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/northstar/utils/Utils.ts b/src/client/northstar/utils/Utils.ts
index d071dec62..09f83ce80 100644
--- a/src/client/northstar/utils/Utils.ts
+++ b/src/client/northstar/utils/Utils.ts
@@ -4,6 +4,12 @@ import { IBaseFilterProvider } from '../core/filter/IBaseFilterProvider';
 import { AggregateFunction } from '../model/idea/idea';
 
 export class Utils {
+    static Emit() {
+        throw new Error("Method not implemented.");
+    }
+    static EmitCallback() {
+        throw new Error("Method not implemented.");
+    }
 
     public static EqualityHelper(a: Object, b: Object): boolean {
         if (a === b) return true;
diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
index bd0bd7f9a..846de4115 100644
--- a/src/client/views/webcam/DashWebRTC.ts
+++ b/src/client/views/webcam/DashWebRTC.ts
@@ -1,4 +1,7 @@
 import { DocServer } from '../../DocServer';
+import { Utils } from '../../../Utils';
+import { MessageStore } from '../../../server/Message';
+
 
 
 /**
@@ -30,8 +33,7 @@ export namespace DashWebRTC {
         offerToReceiveVideo: true
     };
 
-    export function init() {
-        let room = 'test';
+    export function init(room: string) {
 
         if (room !== '') {
             DocServer._socket.emit('create or join', room);
@@ -68,20 +70,21 @@ export namespace DashWebRTC {
         // This client receives a message
         DocServer._socket.on('message', function (message: any) {
             console.log('Client received message:', message);
-            if (message === 'got user media') {
+            if (message.message === 'got user media') {
                 maybeStart();
-            } else if (message.type === 'offer') {
+            } else if (message.message.type === 'offer') {
+                console.log("I have entered here bro!!!");
                 if (!isInitiator && !isStarted) {
                     maybeStart();
                 }
-                pc.setRemoteDescription(new RTCSessionDescription(message));
+                pc.setRemoteDescription(new RTCSessionDescription(message.message));
                 doAnswer();
-            } else if (message.type === 'answer' && isStarted) {
-                pc.setRemoteDescription(new RTCSessionDescription(message));
-            } else if (message.type === 'candidate' && isStarted) {
+            } else if (message.message.type === 'answer' && isStarted) {
+                pc.setRemoteDescription(new RTCSessionDescription(message.message));
+            } else if (message.message.type === 'candidate' && isStarted) {
                 var candidate = new RTCIceCandidate({
-                    sdpMLineIndex: message.label,
-                    candidate: message.candidate
+                    sdpMLineIndex: message.message.label,
+                    candidate: message.message.candidate
                 });
                 pc.addIceCandidate(candidate);
             } else if (message === 'bye' && isStarted) {
@@ -120,7 +123,8 @@ export namespace DashWebRTC {
 
     function sendMessage(message: any) {
         console.log('Client sending message: ', message);
-        DocServer._socket.emit('message', message);
+        Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: "" });
+        //DocServer._socket.emit('message', message);
     }
 
 
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 503b71569..0c4e594e4 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -9,6 +9,7 @@ import "../../views/nodes/WebBox.scss";
 import "./DashWebRTC.scss";
 import adapter from 'webrtc-adapter';
 import { DashWebRTC } from "./DashWebRTC";
+import { DocServer } from "../../DocServer";
 
 
 
@@ -37,11 +38,12 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private callButton: HTMLButtonElement | undefined;
     private startButton: HTMLButtonElement | undefined;
     private hangupButton: HTMLButtonElement | undefined;
+    private roomText: HTMLInputElement | undefined;
 
-    componentDidMount() {
-        // DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
-        DashWebRTC.init();
-    }
+    // componentDidMount() {
+    //     // DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
+    //     //DashWebRTC.init();
+    // }
 
 
     // componentDidMount() {
@@ -279,6 +281,19 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     // }
 
 
+    /**
+      * Function that submits the title entered by user on enter press.
+      */
+    onEnterKeyDown = (e: React.KeyboardEvent) => {
+        if (e.keyCode === 13) {
+            let submittedTitle = this.roomText!.value;
+            this.roomText!.value = "";
+            this.roomText!.blur();
+            DashWebRTC.init(submittedTitle);
+        }
+    }
+
+
 
 
 
@@ -319,6 +334,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     render() {
         let content =
             <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+                <input type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
                 <video id="localVideo" autoPlay playsInline ref={(e) => {
                     this.localVideoEl = e!;
                     DashWebRTC.setLocalVideoObject(e!);
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 60ffa215f..ed778e889 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -63,7 +63,7 @@ export namespace MessageStore {
     export const YoutubeApiQuery = new Message<YoutubeQueryInput>("Youtube Api Query");
     export const DeleteField = new Message<string>("Delete field");
     export const DeleteFields = new Message<string[]>("Delete fields");
-    export const NotifyRoommates = new Message<RoomMessage>("Notify Roommates");
+    export const NotifyRoommates = new Message<RoomMessage>("message");
     export const HangUpCall = new Message<string>("bye");
 
 
-- 
cgit v1.2.3-70-g09d2


From 01c131e8d7ecc2eac68e16a679c40b1156b41391 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <muhammedamoush@gmail.com>
Date: Sat, 7 Dec 2019 16:57:51 -0500
Subject: Adding hang-up functionality

---
 src/client/views/DocumentDecorations.tsx    | 16 +++++++++++++++-
 src/client/views/webcam/DashWebRTC.ts       | 11 ++++++++---
 src/client/views/webcam/DashWebRTCVideo.tsx | 20 +++++++++++++++++++-
 3 files changed, 42 insertions(+), 5 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index b46caf3ea..719a0203b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -39,6 +39,8 @@ library.add(faCloudUploadAlt);
 library.add(faSyncAlt);
 library.add(faShare);
 
+export type CloseCall = (toBeDeleted: DocumentView[]) => void;
+
 @observer
 export class DocumentDecorations extends React.Component<{}, { value: string }> {
     static Instance: DocumentDecorations;
@@ -69,6 +71,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     @observable public isAnimatingFetch = false;
     @observable public isAnimatingPulse = false;
     @observable public openHover = false;
+    @observable private addedCloseCalls: CloseCall[] = [];
+
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -77,6 +81,14 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this._edtingTitle = false);
     }
 
+    addCloseCall = (handler: CloseCall) => {
+        const currentOffset = this.addedCloseCalls.length - 1;
+        this.addedCloseCalls.push((toBeDeleted: DocumentView[]) => {
+            this.addedCloseCalls.splice(currentOffset, 1);
+            handler(toBeDeleted);
+        });
+    }
+
     @action titleChanged = (event: any) => { this._title = event.target.value; };
     @action titleBlur = () => { this._edtingTitle = false; };
     @action titleEntered = (e: any) => {
@@ -239,10 +251,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         e.stopPropagation();
         if (e.button === 0) {
             const recent = Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc) as Doc;
-            SelectionManager.SelectedDocuments().map(dv => {
+            const selectedDocuments = SelectionManager.SelectedDocuments();
+            selectedDocuments.map(dv => {
                 recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
                 dv.props.removeDocument && dv.props.removeDocument(dv.props.Document);
             });
+            this.addedCloseCalls.forEach(handler => handler(selectedDocuments));
             SelectionManager.DeselectAll();
             document.removeEventListener("pointermove", this.onCloseMove);
             document.removeEventListener("pointerup", this.onCloseUp);
diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
index c61469cb8..195f1f0c4 100644
--- a/src/client/views/webcam/DashWebRTC.ts
+++ b/src/client/views/webcam/DashWebRTC.ts
@@ -283,10 +283,15 @@ export namespace DashWebRTC {
         console.log('Remote stream removed. Event: ', event);
     }
 
-    function hangup() {
+    export function hangup() {
         console.log('Hanging up.');
-        stop();
-        sendMessage('bye');
+        if (pc) {
+            stop();
+            sendMessage('bye');
+        }
+        //stop local tracks on hang-up
+        //localVideo.srcObject!.getTracks().forEach(track => track.stop());
+
     }
 
     function handleRemoteHangup() {
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 0c4e594e4..a763fd64c 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -3,13 +3,16 @@ import React = require("react");
 import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView";
 import { FieldViewProps, FieldView } from "../nodes/FieldView";
 import { observable } from "mobx";
-import { DocumentDecorations } from "../DocumentDecorations";
+import { DocumentDecorations, CloseCall } from "../DocumentDecorations";
 import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
 import "./DashWebRTC.scss";
 import adapter from 'webrtc-adapter';
 import { DashWebRTC } from "./DashWebRTC";
 import { DocServer } from "../../DocServer";
+import { DocumentView } from "../nodes/DocumentView";
+import { Utils } from "../../../Utils";
+import { MessageStore } from "../../../server/Message";
 
 
 
@@ -39,6 +42,20 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private startButton: HTMLButtonElement | undefined;
     private hangupButton: HTMLButtonElement | undefined;
     private roomText: HTMLInputElement | undefined;
+    private roomOfCam: string = "";
+
+    componentDidMount() {
+        DocumentDecorations.Instance.addCloseCall(this.closeConnection);
+    }
+
+    closeConnection: CloseCall = () => {
+        //Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: 'bye', room: this.roomOfCam });
+        DashWebRTC.hangup();
+    }
+
+    componentWillUnmount() {
+        // DocumentDecorations.Instance.removeCloseCall(this.closeConnection);
+    }
 
     // componentDidMount() {
     //     // DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
@@ -289,6 +306,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
             let submittedTitle = this.roomText!.value;
             this.roomText!.value = "";
             this.roomText!.blur();
+            this.roomOfCam = submittedTitle;
             DashWebRTC.init(submittedTitle);
         }
     }
-- 
cgit v1.2.3-70-g09d2


From f4382d73eec75f7d7f4bfe6eae3fb1efa128a021 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <muhammedamoush@gmail.com>
Date: Sun, 8 Dec 2019 16:12:16 -0500
Subject: Local Stream tracks stopped when component gets closed

---
 src/client/views/webcam/DashWebRTC.ts       | 13 ++++---------
 src/client/views/webcam/DashWebRTCVideo.tsx |  2 ++
 2 files changed, 6 insertions(+), 9 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
index 195f1f0c4..6c7322a3d 100644
--- a/src/client/views/webcam/DashWebRTC.ts
+++ b/src/client/views/webcam/DashWebRTC.ts
@@ -116,13 +116,6 @@ export namespace DashWebRTC {
     }
 
 
-
-
-    //let socket = io.connect();
-
-
-
-
     function sendMessage(message: any) {
         console.log('Client sending message: ', message);
         Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: curRoom });
@@ -289,8 +282,10 @@ export namespace DashWebRTC {
             stop();
             sendMessage('bye');
         }
-        //stop local tracks on hang-up
-        //localVideo.srcObject!.getTracks().forEach(track => track.stop());
+
+        if (localStream) {
+            localStream.getTracks().forEach(track => track.stop());
+        }
 
     }
 
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index a763fd64c..a9c67f026 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -25,6 +25,7 @@ const offerOptions = {
     offerToReceiveVideo: 1,
 };
 
+
 /**
  * This models the component that will be rendered, that can be used as a doc that will reflect the video cams.
  */
@@ -57,6 +58,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
         // DocumentDecorations.Instance.removeCloseCall(this.closeConnection);
     }
 
+
     // componentDidMount() {
     //     // DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
     //     //DashWebRTC.init();
-- 
cgit v1.2.3-70-g09d2


From cf4a1e62b33ba15b1b376c157d01fb543d34ac73 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Sun, 19 Jan 2020 19:01:10 +0300
Subject: Class refactor

---
 src/client/views/webcam/DashWebRTC.ts       | 227 +++++++++++++++-------------
 src/client/views/webcam/DashWebRTCVideo.tsx |  16 +-
 2 files changed, 130 insertions(+), 113 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
index 6c7322a3d..7d798754f 100644
--- a/src/client/views/webcam/DashWebRTC.ts
+++ b/src/client/views/webcam/DashWebRTC.ts
@@ -7,36 +7,44 @@ import { MessageStore } from '../../../server/Message';
 /**
  * This namespace will have the code required to have functionality code for the usage of webRTC.
  */
-export namespace DashWebRTC {
-
+export class DashWebRTC {
+
+
+    private isChannelReady = false;
+    private isInitiator = false;
+    private isStarted = false;
+    localStream: MediaStream | undefined;
+    private pc: any;
+    remoteStream: MediaStream | undefined;
+    private turnReady: boolean | undefined;
+    localVideo: HTMLVideoElement | undefined;
+    remoteVideo: HTMLVideoElement | undefined;
+    curRoom: string = "";
+
+
+    private pcConfig: any;
+    private sdpConstraints: any;
+
+    constructor() {
+        this.pcConfig = {
+            'iceServers': [{
+                'urls': 'stun:stun.l.google.com:19302'
+            }]
+        };
+
+        // Set up audio and video regardless of what devices are present.
+        this.sdpConstraints = {
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        };
+    }
 
-    let isChannelReady = false;
-    let isInitiator = false;
-    let isStarted = false;
-    let localStream: MediaStream | undefined;
-    let pc: any;
-    let remoteStream: MediaStream | undefined;
-    let turnReady;
-    let localVideo: HTMLVideoElement;
-    let remoteVideo: HTMLVideoElement;
-    let curRoom: string = "";
 
 
-    let pcConfig = {
-        'iceServers': [{
-            'urls': 'stun:stun.l.google.com:19302'
-        }]
-    };
+    init(room: string) {
 
-    // Set up audio and video regardless of what devices are present.
-    let sdpConstraints = {
-        offerToReceiveAudio: true,
-        offerToReceiveVideo: true
-    };
-
-    export function init(room: string) {
-
-        curRoom = room;
+        this.curRoom = room;
+        let self = this;
 
         if (room !== '') {
             DocServer._socket.emit('create or join', room);
@@ -46,7 +54,7 @@ export namespace DashWebRTC {
 
         DocServer._socket.on('created', function (room: string) {
             console.log('Created room ' + room);
-            isInitiator = true;
+            self.isInitiator = true;
         });
 
         DocServer._socket.on('full', function (room: string) {
@@ -56,13 +64,13 @@ export namespace DashWebRTC {
         DocServer._socket.on('join', function (room: string) {
             console.log('Another peer made a request to join room ' + room);
             console.log('This peer is the initiator of room ' + room + '!');
-            isChannelReady = true;
+            self.isChannelReady = true;
         });
 
 
         DocServer._socket.on('joined', function (room: string) {
             console.log('joined: ' + room);
-            isChannelReady = true;
+            self.isChannelReady = true;
         });
 
 
@@ -74,23 +82,23 @@ export namespace DashWebRTC {
         DocServer._socket.on('message', function (message: any) {
             console.log('Client received message:', message);
             if (message.message === 'got user media') {
-                maybeStart();
+                self.maybeStart();
             } else if (message.message.type === 'offer') {
-                if (!isInitiator && !isStarted) {
-                    maybeStart();
+                if (!self.isInitiator && !self.isStarted) {
+                    self.maybeStart();
                 }
-                pc.setRemoteDescription(new RTCSessionDescription(message.message));
-                doAnswer();
-            } else if (message.message.type === 'answer' && isStarted) {
-                pc.setRemoteDescription(new RTCSessionDescription(message.message));
-            } else if (message.message.type === 'candidate' && isStarted) {
+                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+                self.doAnswer();
+            } else if (message.message.type === 'answer' && self.isStarted) {
+                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+            } else if (message.message.type === 'candidate' && self.isStarted) {
                 let candidate = new RTCIceCandidate({
                     sdpMLineIndex: message.message.label,
                     candidate: message.message.candidate
                 });
-                pc.addIceCandidate(candidate);
-            } else if (message === 'bye' && isStarted) {
-                handleRemoteHangup();
+                self.pc.addIceCandidate(candidate);
+            } else if (message === 'bye' && self.isStarted) {
+                self.handleRemoteHangup();
             }
         });
 
@@ -98,16 +106,16 @@ export namespace DashWebRTC {
             audio: false,
             video: true
         })
-            .then(gotStream)
+            .then(this.gotStream)
             .catch(function (e) {
                 alert('getUserMedia() error: ' + e.name);
             });
 
         //Trying this one out!!!
-        console.log('Getting user media with constraints', constraints);
+        console.log('Getting user media with constraints', this.constraints);
 
         if (location.hostname !== 'localhost') {
-            requestTurn(
+            this.requestTurn(
                 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
             );
         }
@@ -116,9 +124,9 @@ export namespace DashWebRTC {
     }
 
 
-    function sendMessage(message: any) {
+    sendMessage(message: any) {
         console.log('Client sending message: ', message);
-        Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: curRoom });
+        Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
         //DocServer._socket.emit('message', message);
     }
 
@@ -126,33 +134,33 @@ export namespace DashWebRTC {
 
 
 
-    export function setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
+    setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
         localVideo = localVideo;
         remoteVideo = remoteVideo;
     }
 
-    export function setLocalVideoObject(localVideoRef: HTMLVideoElement) {
-        localVideo = localVideoRef;
+    setLocalVideoObject(localVideoRef: HTMLVideoElement) {
+        this.localVideo = localVideoRef;
     }
 
-    export function setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
-        remoteVideo = remoteVideoRef;
+    setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
+        this.remoteVideo = remoteVideoRef;
     }
 
 
 
 
-    function gotStream(stream: any) {
+    gotStream(stream: any) {
         console.log('Adding local stream.');
-        localStream = stream;
-        localVideo.srcObject = stream;
-        sendMessage('got user media');
-        if (isInitiator) {
-            maybeStart();
+        this.localStream = stream;
+        this.localVideo!.srcObject = stream;
+        this.sendMessage('got user media');
+        if (this.isInitiator) {
+            this.maybeStart();
         }
     }
 
-    let constraints = {
+    constraints = {
         video: true,
         audio: true
     };
@@ -161,32 +169,32 @@ export namespace DashWebRTC {
 
 
 
-    function maybeStart() {
-        console.log('>>>>>>> maybeStart() ', isStarted, localStream, isChannelReady);
-        if (!isStarted && typeof localStream !== 'undefined' && isChannelReady) {
+    maybeStart() {
+        console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
+        if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
             console.log('>>>>>> creating peer connection');
-            createPeerConnection();
-            pc.addStream(localStream);
-            isStarted = true;
-            console.log('isInitiator', isInitiator);
-            if (isInitiator) {
-                doCall();
+            this.createPeerConnection();
+            this.pc.addStream(this.localStream);
+            this.isStarted = true;
+            console.log('isInitiator', this.isInitiator);
+            if (this.isInitiator) {
+                this.doCall();
             }
         }
     }
 
 
-    //this will need to be changed to our version of hangUp
-    window.onbeforeunload = function () {
-        sendMessage('bye');
-    };
+    // //this will need to be changed to our version of hangUp
+    // window.onbeforeunload = function () {
+    //     sendMessage('bye');
+    // };
 
-    function createPeerConnection() {
+    createPeerConnection() {
         try {
-            pc = new RTCPeerConnection(undefined);
-            pc.onicecandidate = handleIceCandidate;
-            pc.onaddstream = handleRemoteStreamAdded;
-            pc.onremovestream = handleRemoteStreamRemoved;
+            this.pc = new RTCPeerConnection(undefined);
+            this.pc.onicecandidate = this.handleIceCandidate;
+            this.pc.onaddstream = this.handleRemoteStreamAdded;
+            this.pc.onremovestream = this.handleRemoteStreamRemoved;
             console.log('Created RTCPeerConnnection');
         } catch (e) {
             console.log('Failed to create PeerConnection, exception: ' + e.message);
@@ -195,10 +203,10 @@ export namespace DashWebRTC {
         }
     }
 
-    function handleIceCandidate(event: any) {
+    handleIceCandidate(event: any) {
         console.log('icecandidate event: ', event);
         if (event.candidate) {
-            sendMessage({
+            this.sendMessage({
                 type: 'candidate',
                 label: event.candidate.sdpMLineIndex,
                 id: event.candidate.sdpMid,
@@ -209,40 +217,41 @@ export namespace DashWebRTC {
         }
     }
 
-    function handleCreateOfferError(event: any) {
+    handleCreateOfferError(event: any) {
         console.log('createOffer() error: ', event);
     }
 
-    function doCall() {
+    doCall() {
         console.log('Sending offer to peer');
-        pc.createOffer(setLocalAndSendMessage, handleCreateOfferError);
+        this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
     }
 
-    function doAnswer() {
+    doAnswer() {
         console.log('Sending answer to peer.');
-        pc.createAnswer().then(
-            setLocalAndSendMessage,
-            onCreateSessionDescriptionError
+        this.pc.createAnswer().then(
+            this.setLocalAndSendMessage,
+            this.onCreateSessionDescriptionError
         );
     }
 
-    function setLocalAndSendMessage(sessionDescription: any) {
-        pc.setLocalDescription(sessionDescription);
+    setLocalAndSendMessage(sessionDescription: any) {
+        this.pc.setLocalDescription(sessionDescription);
         console.log('setLocalAndSendMessage sending message', sessionDescription);
-        sendMessage(sessionDescription);
+        this.sendMessage(sessionDescription);
     }
 
-    function onCreateSessionDescriptionError(error: any) {
+    onCreateSessionDescriptionError(error: any) {
         console.log('Failed to create session description: ' + error.toString());
     }
 
 
-    function requestTurn(turnURL: any) {
+    requestTurn(turnURL: any) {
         var turnExists = false;
-        for (var i in pcConfig.iceServers) {
-            if (pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
+        let self = this;
+        for (var i in this.pcConfig.iceServers) {
+            if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
                 turnExists = true;
-                turnReady = true;
+                this.turnReady = true;
                 break;
             }
         }
@@ -254,11 +263,11 @@ export namespace DashWebRTC {
                 if (xhr.readyState === 4 && xhr.status === 200) {
                     var turnServer = JSON.parse(xhr.responseText);
                     console.log('Got TURN server: ', turnServer);
-                    pcConfig.iceServers.push({
+                    self.pcConfig.iceServers.push({
                         'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
                         //'credential': turnServer.password
                     });
-                    turnReady = true;
+                    self.turnReady = true;
                 }
             };
             xhr.open('GET', turnURL, true);
@@ -266,39 +275,39 @@ export namespace DashWebRTC {
         }
     }
 
-    function handleRemoteStreamAdded(event: MediaStreamEvent) {
+    handleRemoteStreamAdded(event: MediaStreamEvent) {
         console.log('Remote stream added.');
-        remoteStream = event.stream!;
-        remoteVideo.srcObject = remoteStream;
+        this.remoteStream = event.stream!;
+        this.remoteVideo!.srcObject = this.remoteStream;
     }
 
-    function handleRemoteStreamRemoved(event: MediaStreamEvent) {
+    handleRemoteStreamRemoved(event: MediaStreamEvent) {
         console.log('Remote stream removed. Event: ', event);
     }
 
-    export function hangup() {
+    hangup() {
         console.log('Hanging up.');
-        if (pc) {
+        if (this.pc) {
             stop();
-            sendMessage('bye');
+            this.sendMessage('bye');
         }
 
-        if (localStream) {
-            localStream.getTracks().forEach(track => track.stop());
+        if (this.localStream) {
+            this.localStream.getTracks().forEach(track => track.stop());
         }
 
     }
 
-    function handleRemoteHangup() {
+    handleRemoteHangup() {
         console.log('Session terminated.');
         stop();
-        isInitiator = false;
+        this.isInitiator = false;
     }
 
-    function stop() {
-        isStarted = false;
-        pc.close();
-        pc = null;
+    stop() {
+        this.isStarted = false;
+        this.pc.close();
+        this.pc = null;
     }
 
 
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index a9c67f026..7b091062c 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -44,14 +44,20 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private hangupButton: HTMLButtonElement | undefined;
     private roomText: HTMLInputElement | undefined;
     private roomOfCam: string = "";
+    private webRTCManager: DashWebRTC | undefined;
 
     componentDidMount() {
         DocumentDecorations.Instance.addCloseCall(this.closeConnection);
+        this.webRTCManager = new DashWebRTC();
+        let self = this;
+        window.onbeforeunload = function () {
+            self.webRTCManager!.sendMessage('bye');
+        };
     }
 
     closeConnection: CloseCall = () => {
         //Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: 'bye', room: this.roomOfCam });
-        DashWebRTC.hangup();
+        this.webRTCManager!.hangup();
     }
 
     componentWillUnmount() {
@@ -309,7 +315,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
             this.roomText!.value = "";
             this.roomText!.blur();
             this.roomOfCam = submittedTitle;
-            DashWebRTC.init(submittedTitle);
+            this.webRTCManager!.init(submittedTitle);
         }
     }
 
@@ -327,6 +333,8 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
 
 
 
+
+
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebRTCVideo, fieldKey); }
 
 
@@ -357,11 +365,11 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
                 <input type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
                 <video id="localVideo" autoPlay playsInline ref={(e) => {
                     this.localVideoEl = e!;
-                    DashWebRTC.setLocalVideoObject(e!);
+                    this.webRTCManager!.setLocalVideoObject(e!);
                 }}></video>
                 <video id="remoteVideo" autoPlay playsInline ref={(e) => {
                     this.peerVideoEl = e!;
-                    DashWebRTC.setRemoteVideoObject(e!);
+                    this.webRTCManager!.setRemoteVideoObject(e!);
                 }}></video>
                 {/* <button id="startButton" ref={(e) => this.startButton = e!} onClick={this.startAction}>Start</button>
                 <button id="callButton" ref={(e) => this.callButton = e!} onClick={this.callAction}>Call</button>
-- 
cgit v1.2.3-70-g09d2


From 8e8533a7bab97fe9be8c8fb862a7e809da5f137d Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Tue, 21 Jan 2020 18:46:32 -0500
Subject: Moved everything into component

Need help with server side
---
 src/client/views/webcam/DashWebRTC.ts       | 596 ++++++++++++++--------------
 src/client/views/webcam/DashWebRTCVideo.tsx | 475 +++++++++++-----------
 src/server/index.ts                         |  90 +++--
 3 files changed, 596 insertions(+), 565 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
index 7d798754f..ef5ecf0fc 100644
--- a/src/client/views/webcam/DashWebRTC.ts
+++ b/src/client/views/webcam/DashWebRTC.ts
@@ -1,314 +1,314 @@
-import { DocServer } from '../../DocServer';
-import { Utils } from '../../../Utils';
-import { MessageStore } from '../../../server/Message';
-
-
-
-/**
- * This namespace will have the code required to have functionality code for the usage of webRTC.
- */
-export class DashWebRTC {
-
-
-    private isChannelReady = false;
-    private isInitiator = false;
-    private isStarted = false;
-    localStream: MediaStream | undefined;
-    private pc: any;
-    remoteStream: MediaStream | undefined;
-    private turnReady: boolean | undefined;
-    localVideo: HTMLVideoElement | undefined;
-    remoteVideo: HTMLVideoElement | undefined;
-    curRoom: string = "";
-
-
-    private pcConfig: any;
-    private sdpConstraints: any;
-
-    constructor() {
-        this.pcConfig = {
-            'iceServers': [{
-                'urls': 'stun:stun.l.google.com:19302'
-            }]
-        };
+// import { DocServer } from '../../DocServer';
+// import { Utils } from '../../../Utils';
+// import { MessageStore } from '../../../server/Message';
+
+
+
+// /**
+//  * This namespace will have the code required to have functionality code for the usage of webRTC.
+//  */
+// export class DashWebRTC {
+
+
+//     private isChannelReady = false;
+//     private isInitiator = false;
+//     private isStarted = false;
+//     localStream: MediaStream | undefined;
+//     private pc: any;
+//     remoteStream: MediaStream | undefined;
+//     private turnReady: boolean | undefined;
+//     localVideo: HTMLVideoElement | undefined;
+//     remoteVideo: HTMLVideoElement | undefined;
+//     curRoom: string = "";
+
+
+//     private pcConfig: any;
+//     private sdpConstraints: any;
+
+//     constructor() {
+//         this.pcConfig = {
+//             'iceServers': [{
+//                 'urls': 'stun:stun.l.google.com:19302'
+//             }]
+//         };
 
-        // Set up audio and video regardless of what devices are present.
-        this.sdpConstraints = {
-            offerToReceiveAudio: true,
-            offerToReceiveVideo: true
-        };
-    }
+//         // Set up audio and video regardless of what devices are present.
+//         this.sdpConstraints = {
+//             offerToReceiveAudio: true,
+//             offerToReceiveVideo: true
+//         };
+//     }
 
 
 
-    init(room: string) {
+//     init(room: string) {
 
-        this.curRoom = room;
-        let self = this;
+//         this.curRoom = room;
+//         let self = this;
 
-        if (room !== '') {
-            DocServer._socket.emit('create or join', room);
-            console.log('Attempted to create or  join room', room);
+//         if (room !== '') {
+//             DocServer._socket.emit('create or join', room);
+//             console.log('Attempted to create or  join room', room);
 
-        }
+//         }
 
-        DocServer._socket.on('created', function (room: string) {
-            console.log('Created room ' + room);
-            self.isInitiator = true;
-        });
+//         DocServer._socket.on('created', function (room: string) {
+//             console.log('Created room ' + room);
+//             self.isInitiator = true;
+//         });
 
-        DocServer._socket.on('full', function (room: string) {
-            console.log('Room ' + room + ' is full');
-        });
+//         DocServer._socket.on('full', function (room: string) {
+//             console.log('Room ' + room + ' is full');
+//         });
 
-        DocServer._socket.on('join', function (room: string) {
-            console.log('Another peer made a request to join room ' + room);
-            console.log('This peer is the initiator of room ' + room + '!');
-            self.isChannelReady = true;
-        });
+//         DocServer._socket.on('join', function (room: string) {
+//             console.log('Another peer made a request to join room ' + room);
+//             console.log('This peer is the initiator of room ' + room + '!');
+//             self.isChannelReady = true;
+//         });
 
 
-        DocServer._socket.on('joined', function (room: string) {
-            console.log('joined: ' + room);
-            self.isChannelReady = true;
-        });
+//         DocServer._socket.on('joined', function (room: string) {
+//             console.log('joined: ' + room);
+//             self.isChannelReady = true;
+//         });
 
 
-        DocServer._socket.on('log', function (array: any) {
-            console.log.apply(console, array);
-        });
+//         DocServer._socket.on('log', function (array: any) {
+//             console.log.apply(console, array);
+//         });
 
-        // This client receives a message
-        DocServer._socket.on('message', function (message: any) {
-            console.log('Client received message:', message);
-            if (message.message === 'got user media') {
-                self.maybeStart();
-            } else if (message.message.type === 'offer') {
-                if (!self.isInitiator && !self.isStarted) {
-                    self.maybeStart();
-                }
-                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-                self.doAnswer();
-            } else if (message.message.type === 'answer' && self.isStarted) {
-                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-            } else if (message.message.type === 'candidate' && self.isStarted) {
-                let candidate = new RTCIceCandidate({
-                    sdpMLineIndex: message.message.label,
-                    candidate: message.message.candidate
-                });
-                self.pc.addIceCandidate(candidate);
-            } else if (message === 'bye' && self.isStarted) {
-                self.handleRemoteHangup();
-            }
-        });
+//         // This client receives a message
+//         DocServer._socket.on('message', function (message: any) {
+//             console.log('Client received message:', message);
+//             if (message.message === 'got user media') {
+//                 self.maybeStart();
+//             } else if (message.message.type === 'offer') {
+//                 if (!self.isInitiator && !self.isStarted) {
+//                     self.maybeStart();
+//                 }
+//                 self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+//                 self.doAnswer();
+//             } else if (message.message.type === 'answer' && self.isStarted) {
+//                 self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+//             } else if (message.message.type === 'candidate' && self.isStarted) {
+//                 let candidate = new RTCIceCandidate({
+//                     sdpMLineIndex: message.message.label,
+//                     candidate: message.message.candidate
+//                 });
+//                 self.pc.addIceCandidate(candidate);
+//             } else if (message === 'bye' && self.isStarted) {
+//                 self.handleRemoteHangup();
+//             }
+//         });
 
-        navigator.mediaDevices.getUserMedia({
-            audio: false,
-            video: true
-        })
-            .then(this.gotStream)
-            .catch(function (e) {
-                alert('getUserMedia() error: ' + e.name);
-            });
-
-        //Trying this one out!!!
-        console.log('Getting user media with constraints', this.constraints);
-
-        if (location.hostname !== 'localhost') {
-            this.requestTurn(
-                'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
-            );
-        }
-
-
-    }
-
-
-    sendMessage(message: any) {
-        console.log('Client sending message: ', message);
-        Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
-        //DocServer._socket.emit('message', message);
-    }
-
-
-
-
-
-    setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
-        localVideo = localVideo;
-        remoteVideo = remoteVideo;
-    }
-
-    setLocalVideoObject(localVideoRef: HTMLVideoElement) {
-        this.localVideo = localVideoRef;
-    }
-
-    setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
-        this.remoteVideo = remoteVideoRef;
-    }
-
-
-
-
-    gotStream(stream: any) {
-        console.log('Adding local stream.');
-        this.localStream = stream;
-        this.localVideo!.srcObject = stream;
-        this.sendMessage('got user media');
-        if (this.isInitiator) {
-            this.maybeStart();
-        }
-    }
-
-    constraints = {
-        video: true,
-        audio: true
-    };
-
-
-
-
-
-    maybeStart() {
-        console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
-        if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
-            console.log('>>>>>> creating peer connection');
-            this.createPeerConnection();
-            this.pc.addStream(this.localStream);
-            this.isStarted = true;
-            console.log('isInitiator', this.isInitiator);
-            if (this.isInitiator) {
-                this.doCall();
-            }
-        }
-    }
-
-
-    // //this will need to be changed to our version of hangUp
-    // window.onbeforeunload = function () {
-    //     sendMessage('bye');
-    // };
-
-    createPeerConnection() {
-        try {
-            this.pc = new RTCPeerConnection(undefined);
-            this.pc.onicecandidate = this.handleIceCandidate;
-            this.pc.onaddstream = this.handleRemoteStreamAdded;
-            this.pc.onremovestream = this.handleRemoteStreamRemoved;
-            console.log('Created RTCPeerConnnection');
-        } catch (e) {
-            console.log('Failed to create PeerConnection, exception: ' + e.message);
-            alert('Cannot create RTCPeerConnection object.');
-            return;
-        }
-    }
-
-    handleIceCandidate(event: any) {
-        console.log('icecandidate event: ', event);
-        if (event.candidate) {
-            this.sendMessage({
-                type: 'candidate',
-                label: event.candidate.sdpMLineIndex,
-                id: event.candidate.sdpMid,
-                candidate: event.candidate.candidate
-            });
-        } else {
-            console.log('End of candidates.');
-        }
-    }
-
-    handleCreateOfferError(event: any) {
-        console.log('createOffer() error: ', event);
-    }
-
-    doCall() {
-        console.log('Sending offer to peer');
-        this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
-    }
-
-    doAnswer() {
-        console.log('Sending answer to peer.');
-        this.pc.createAnswer().then(
-            this.setLocalAndSendMessage,
-            this.onCreateSessionDescriptionError
-        );
-    }
-
-    setLocalAndSendMessage(sessionDescription: any) {
-        this.pc.setLocalDescription(sessionDescription);
-        console.log('setLocalAndSendMessage sending message', sessionDescription);
-        this.sendMessage(sessionDescription);
-    }
-
-    onCreateSessionDescriptionError(error: any) {
-        console.log('Failed to create session description: ' + error.toString());
-    }
-
-
-    requestTurn(turnURL: any) {
-        var turnExists = false;
-        let self = this;
-        for (var i in this.pcConfig.iceServers) {
-            if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
-                turnExists = true;
-                this.turnReady = true;
-                break;
-            }
-        }
-        if (!turnExists) {
-            console.log('Getting TURN server from ', turnURL);
-            // No TURN server. Get one from computeengineondemand.appspot.com:
-            var xhr = new XMLHttpRequest();
-            xhr.onreadystatechange = function () {
-                if (xhr.readyState === 4 && xhr.status === 200) {
-                    var turnServer = JSON.parse(xhr.responseText);
-                    console.log('Got TURN server: ', turnServer);
-                    self.pcConfig.iceServers.push({
-                        'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
-                        //'credential': turnServer.password
-                    });
-                    self.turnReady = true;
-                }
-            };
-            xhr.open('GET', turnURL, true);
-            xhr.send();
-        }
-    }
-
-    handleRemoteStreamAdded(event: MediaStreamEvent) {
-        console.log('Remote stream added.');
-        this.remoteStream = event.stream!;
-        this.remoteVideo!.srcObject = this.remoteStream;
-    }
-
-    handleRemoteStreamRemoved(event: MediaStreamEvent) {
-        console.log('Remote stream removed. Event: ', event);
-    }
-
-    hangup() {
-        console.log('Hanging up.');
-        if (this.pc) {
-            stop();
-            this.sendMessage('bye');
-        }
-
-        if (this.localStream) {
-            this.localStream.getTracks().forEach(track => track.stop());
-        }
-
-    }
-
-    handleRemoteHangup() {
-        console.log('Session terminated.');
-        stop();
-        this.isInitiator = false;
-    }
-
-    stop() {
-        this.isStarted = false;
-        this.pc.close();
-        this.pc = null;
-    }
-
-
-}
\ No newline at end of file
+//         navigator.mediaDevices.getUserMedia({
+//             audio: false,
+//             video: true
+//         })
+//             .then(this.gotStream)
+//             .catch(function (e) {
+//                 alert('getUserMedia() error: ' + e.name);
+//             });
+
+//         //Trying this one out!!!
+//         console.log('Getting user media with constraints', this.constraints);
+
+//         if (location.hostname !== 'localhost') {
+//             this.requestTurn(
+//                 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
+//             );
+//         }
+
+
+//     }
+
+
+//     sendMessage(message: any) {
+//         console.log('Client sending message: ', message);
+//         Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
+//         //DocServer._socket.emit('message', message);
+//     }
+
+
+
+
+
+//     setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
+//         this.localVideo = localVideo;
+//         this.remoteVideo = remoteVideo;
+//     }
+
+//     setLocalVideoObject(localVideoRef: HTMLVideoElement) {
+//         this.localVideo = localVideoRef;
+//     }
+
+//     setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
+//         this.remoteVideo = remoteVideoRef;
+//     }
+
+
+
+
+//     gotStream(stream: any) {
+//         console.log('Adding local stream.');
+//         this.localStream = stream;
+//         this.localVideo!.srcObject = stream;
+//         this.sendMessage('got user media');
+//         if (this.isInitiator) {
+//             this.maybeStart();
+//         }
+//     }
+
+//     constraints = {
+//         video: true,
+//         audio: true
+//     };
+
+
+
+
+
+//     maybeStart() {
+//         console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
+//         if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
+//             console.log('>>>>>> creating peer connection');
+//             this.createPeerConnection();
+//             this.pc.addStream(this.localStream);
+//             this.isStarted = true;
+//             console.log('isInitiator', this.isInitiator);
+//             if (this.isInitiator) {
+//                 this.doCall();
+//             }
+//         }
+//     }
+
+
+//     // //this will need to be changed to our version of hangUp
+//     // window.onbeforeunload = function () {
+//     //     sendMessage('bye');
+//     // };
+
+//     createPeerConnection() {
+//         try {
+//             this.pc = new RTCPeerConnection(undefined);
+//             this.pc.onicecandidate = this.handleIceCandidate;
+//             this.pc.onaddstream = this.handleRemoteStreamAdded;
+//             this.pc.onremovestream = this.handleRemoteStreamRemoved;
+//             console.log('Created RTCPeerConnnection');
+//         } catch (e) {
+//             console.log('Failed to create PeerConnection, exception: ' + e.message);
+//             alert('Cannot create RTCPeerConnection object.');
+//             return;
+//         }
+//     }
+
+//     handleIceCandidate(event: any) {
+//         console.log('icecandidate event: ', event);
+//         if (event.candidate) {
+//             this.sendMessage({
+//                 type: 'candidate',
+//                 label: event.candidate.sdpMLineIndex,
+//                 id: event.candidate.sdpMid,
+//                 candidate: event.candidate.candidate
+//             });
+//         } else {
+//             console.log('End of candidates.');
+//         }
+//     }
+
+//     handleCreateOfferError(event: any) {
+//         console.log('createOffer() error: ', event);
+//     }
+
+//     doCall() {
+//         console.log('Sending offer to peer');
+//         this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
+//     }
+
+//     doAnswer() {
+//         console.log('Sending answer to peer.');
+//         this.pc.createAnswer().then(
+//             this.setLocalAndSendMessage,
+//             this.onCreateSessionDescriptionError
+//         );
+//     }
+
+//     setLocalAndSendMessage(sessionDescription: any) {
+//         this.pc.setLocalDescription(sessionDescription);
+//         console.log('setLocalAndSendMessage sending message', sessionDescription);
+//         this.sendMessage(sessionDescription);
+//     }
+
+//     onCreateSessionDescriptionError(error: any) {
+//         console.log('Failed to create session description: ' + error.toString());
+//     }
+
+
+//     requestTurn(turnURL: any) {
+//         var turnExists = false;
+//         let self = this;
+//         for (var i in this.pcConfig.iceServers) {
+//             if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
+//                 turnExists = true;
+//                 this.turnReady = true;
+//                 break;
+//             }
+//         }
+//         if (!turnExists) {
+//             console.log('Getting TURN server from ', turnURL);
+//             // No TURN server. Get one from computeengineondemand.appspot.com:
+//             var xhr = new XMLHttpRequest();
+//             xhr.onreadystatechange = function () {
+//                 if (xhr.readyState === 4 && xhr.status === 200) {
+//                     var turnServer = JSON.parse(xhr.responseText);
+//                     console.log('Got TURN server: ', turnServer);
+//                     self.pcConfig.iceServers.push({
+//                         'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
+//                         //'credential': turnServer.password
+//                     });
+//                     self.turnReady = true;
+//                 }
+//             };
+//             xhr.open('GET', turnURL, true);
+//             xhr.send();
+//         }
+//     }
+
+//     handleRemoteStreamAdded(event: MediaStreamEvent) {
+//         console.log('Remote stream added.');
+//         this.remoteStream = event.stream!;
+//         this.remoteVideo!.srcObject = this.remoteStream;
+//     }
+
+//     handleRemoteStreamRemoved(event: MediaStreamEvent) {
+//         console.log('Remote stream removed. Event: ', event);
+//     }
+
+//     hangup() {
+//         console.log('Hanging up.');
+//         if (this.pc) {
+//             stop();
+//             this.sendMessage('bye');
+//         }
+
+//         if (this.localStream) {
+//             this.localStream.getTracks().forEach(track => track.stop());
+//         }
+
+//     }
+
+//     handleRemoteHangup() {
+//         console.log('Session terminated.');
+//         stop();
+//         this.isInitiator = false;
+//     }
+
+//     stop() {
+//         this.isStarted = false;
+//         this.pc.close();
+//         this.pc = null;
+//     }
+
+
+// }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 7b091062c..acba95354 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -8,7 +8,6 @@ import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
 import "./DashWebRTC.scss";
 import adapter from 'webrtc-adapter';
-import { DashWebRTC } from "./DashWebRTC";
 import { DocServer } from "../../DocServer";
 import { DocumentView } from "../nodes/DocumentView";
 import { Utils } from "../../../Utils";
@@ -34,307 +33,337 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
 
     @observable private localVideoEl: HTMLVideoElement | undefined;
     @observable private peerVideoEl: HTMLVideoElement | undefined;
-    @observable private localStream: MediaStream | undefined;
-    @observable private startTime: any = null;
-    @observable private remoteStream: MediaStream | undefined;
-    @observable private localPeerConnection: any;
-    @observable private remotePeerConnection: any;
-    private callButton: HTMLButtonElement | undefined;
-    private startButton: HTMLButtonElement | undefined;
-    private hangupButton: HTMLButtonElement | undefined;
     private roomText: HTMLInputElement | undefined;
     private roomOfCam: string = "";
-    private webRTCManager: DashWebRTC | undefined;
+    private isChannelReady = false;
+    private isInitiator = false;
+    private isStarted = false;
+    localStream: MediaStream | undefined;
+    private pc: any;
+    remoteStream: MediaStream | undefined;
+    private turnReady: boolean | undefined;
+    //localVideo: HTMLVideoElement | undefined;
+    //remoteVideo: HTMLVideoElement | undefined;
+    curRoom: string = "";
+
+
+    private pcConfig = {
+        'iceServers': [{
+            'urls': 'stun:stun.l.google.com:19302'
+        }]
+    };
+
+    // Set up audio and video regardless of what devices are present.
+    private sdpConstraints = {
+        offerToReceiveAudio: true,
+        offerToReceiveVideo: true
+    };
 
     componentDidMount() {
         DocumentDecorations.Instance.addCloseCall(this.closeConnection);
-        this.webRTCManager = new DashWebRTC();
         let self = this;
         window.onbeforeunload = function () {
-            self.webRTCManager!.sendMessage('bye');
+            self.sendMessage('bye');
         };
     }
 
     closeConnection: CloseCall = () => {
-        //Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: 'bye', room: this.roomOfCam });
-        this.webRTCManager!.hangup();
+        this.hangup();
     }
 
     componentWillUnmount() {
-        // DocumentDecorations.Instance.removeCloseCall(this.closeConnection);
     }
 
 
-    // componentDidMount() {
-    //     // DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!);
-    //     //DashWebRTC.init();
-    // }
-
-
-    // componentDidMount() {
-    //     this.callButton!.disabled = true;
-    //     this.hangupButton!.disabled = true;
-    //     // navigator.mediaDevices.getUserMedia(mediaStreamConstraints).then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError);
-    //     this.localVideoEl!.addEventListener('loadedmetadata', this.logVideoLoaded);
-    //     this.peerVideoEl!.addEventListener('loadedmetadata', this.logVideoLoaded);
-    //     this.peerVideoEl!.addEventListener('onresize', this.logResizedVideo);
-    // }
-
-
-    // gotLocalMediaStream = (mediaStream: MediaStream) => {
-    //     this.localStream = mediaStream;
-    //     if (this.localVideoEl) {
-    //         this.localVideoEl.srcObject = mediaStream;
-    //     }
-    //     this.trace('Received local stream.');
-    //     this.callButton!.disabled = false;
-
-    // }
-
-    // gotRemoteMediaStream = (event: MediaStreamEvent) => {
-    //     let mediaStream = event.stream;
-    //     this.peerVideoEl!.srcObject = mediaStream;
-    //     this.remoteStream = mediaStream!;
+    init(room: string) {
 
-    // }
+        this.curRoom = room;
+        let self = this;
 
-    // handleLocalMediaStreamError = (error: string) => {
-    //     //console.log("navigator.getUserMedia error: ", error);
-    //     this.trace(`navigator.getUserMedia error: ${error.toString()}.`);
+        if (room !== '') {
+            DocServer._socket.emit('create or join', room);
+            console.log('Attempted to create or  join room', room);
 
-    // }
-
-    // logVideoLoaded = (event: any) => {
-    //     let video = event.target;
-    //     this.trace(`${video.id} videoWidth: ${video.videoWidth}px, ` +
-    //         `videoHeight: ${video.videoHeight}px.`);
-    // }
+        }
 
-    // logResizedVideo = (event: any) => {
-    //     this.logVideoLoaded(event);
+        DocServer._socket.on('created', function (room: string) {
+            console.log('Created room ' + room);
+            self.isInitiator = true;
+        });
+
+        DocServer._socket.on('full', function (room: string) {
+            console.log('Room ' + room + ' is full');
+        });
+
+        DocServer._socket.on('join', function (room: string) {
+            console.log('Another peer made a request to join room ' + room);
+            console.log('This peer is the initiator of room ' + room + '!');
+            self.isChannelReady = true;
+        });
+
+
+        DocServer._socket.on('joined', function (room: string) {
+            console.log('joined: ' + room);
+            self.isChannelReady = true;
+        });
+
+
+        DocServer._socket.on('log', function (array: any) {
+            console.log.apply(console, array);
+        });
+
+        // This client receives a message
+        DocServer._socket.on('message', function (message: any) {
+            console.log('Client received message:', message);
+            if (message.message === 'got user media') {
+                self.maybeStart();
+            } else if (message.message.type === 'offer') {
+                if (!self.isInitiator && !self.isStarted) {
+                    self.maybeStart();
+                }
+                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+                self.doAnswer();
+            } else if (message.message.type === 'answer' && self.isStarted) {
+                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+            } else if (message.message.type === 'candidate' && self.isStarted) {
+                let candidate = new RTCIceCandidate({
+                    sdpMLineIndex: message.message.label,
+                    candidate: message.message.candidate
+                });
+                self.pc.addIceCandidate(candidate);
+            } else if (message === 'bye' && self.isStarted) {
+                self.handleRemoteHangup();
+            }
+        });
+
+        navigator.mediaDevices.getUserMedia({
+            audio: false,
+            video: true
+        })
+            .then(this.gotStream)
+            .catch(function (e) {
+                alert('getUserMedia() error: ' + e.name);
+            });
+
+        //Trying this one out!!!
+        console.log('Getting user media with constraints', this.constraints);
+
+        if (location.hostname !== 'localhost') {
+            this.requestTurn(
+                'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
+            );
+        }
 
-    //     if (this.startTime) {
-    //         let elapsedTime = window.performance.now() - this.startTime;
-    //         this.startTime = null;
-    //         this.trace(`Setup time: ${elapsedTime.toFixed(3)}ms.`);
-    //     }
 
-    // }
+    }
 
-    // handleConnection = (event: any) => {
-    //     let peerConnection = event.target;
-    //     let iceCandidate = event.candidate;
 
-    //     if (iceCandidate) {
-    //         let newIceCandidate: RTCIceCandidate = new RTCIceCandidate(iceCandidate);
-    //         let otherPeer: any = this.getOtherPeer(peerConnection);
+    private sendMessage = (message: any) => {
+        console.log('Client sending message: ', message);
+        Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
+        //DocServer._socket.emit('message', message);
+    }
 
-    //         otherPeer.addIceCandidate(newIceCandidate).then(() => {
-    //             this.handleConnectionSuccess(peerConnection);
-    //         }).catch((error: any) => {
-    //             this.handleConnectionFailure(peerConnection, error);
-    //         });
 
-    //         this.trace(`${this.getPeerName(peerConnection)} ICE candidate:\n` +
-    //             `${event.candidate.candidate}.`);
 
-    //     }
-    // }
 
-    // // Logs that the connection succeeded.
-    // handleConnectionSuccess = (peerConnection: any) => {
-    //     this.trace(`${this.getPeerName(peerConnection)} addIceCandidate success.`);
-    // }
 
-    // handleConnectionFailure = (peerConnection: any, error: any) => {
-    //     this.trace(`${this.getPeerName(peerConnection)} failed to add ICE Candidate:\n` +
-    //         `${error.toString()}.`);
+    // setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
+    //     this.localVideo = localVideo;
+    //     this.remoteVideo = remoteVideo;
     // }
 
-    // // Logs changes to the connection state.
-    // handleConnectionChange = (event: any) => {
-    //     let peerConnection = event.target;
-    //     console.log('ICE state change event: ', event);
-    //     this.trace(`${this.getPeerName(peerConnection)} ICE state: ` +
-    //         `${peerConnection.iceConnectionState}.`);
-    // }
+    // setLocalVideoObject(localVideoRef: HTMLVideoElement) {
+    //     this.localVideo = localVideoRef;
 
-    // // Logs error when setting session description fails.
-    // setSessionDescriptionError = (error: any) => {
-    //     this.trace(`Failed to create session description: ${error.toString()}.`);
     // }
 
-    // // Logs success when setting session description.
-    // setDescriptionSuccess = (peerConnection: any, functionName: any) => {
-    //     let peerName = this.getPeerName(peerConnection);
-    //     this.trace(`${peerName} ${functionName} complete.`);
+    // setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
+    //     this.remoteVideo = remoteVideoRef;
     // }
 
 
-    // // Logs success when localDescription is set.
-    // setLocalDescriptionSuccess = (peerConnection: any) => {
-    //     this.setDescriptionSuccess(peerConnection, 'setLocalDescription');
-    // }
 
-    // // Logs success when remoteDescription is set.
-    // setRemoteDescriptionSuccess = (peerConnection: any) => {
-    //     this.setDescriptionSuccess(peerConnection, 'setRemoteDescription');
-    // }
 
-    // createdOffer = (description: any) => {
-    //     this.trace(`Offer from localPeerConnection:\n${description.sdp}`);
-    //     this.trace('localPeerConnection setLocalDescription start.');
+    private gotStream = (stream: any) => {
+        console.log('Adding local stream.');
+        this.localStream = stream;
+        this.localVideoEl!.srcObject = stream;
+        this.sendMessage('got user media');
+        if (this.isInitiator) {
+            this.maybeStart();
+        }
+    }
 
-    //     this.localPeerConnection.setLocalDescription(description).then(() => {
-    //         this.setLocalDescriptionSuccess(this.localPeerConnection);
-    //     }).catch(this.setSessionDescriptionError);
+    constraints = {
+        video: true,
+        audio: true
+    };
 
 
-    //     this.trace('remotePeerConnection setRemoteDescription start.');
-    //     this.remotePeerConnection.setRemoteDescription(description)
-    //         .then(() => {
-    //             this.setRemoteDescriptionSuccess(this.remotePeerConnection);
-    //         }).catch(this.setSessionDescriptionError);
 
-    //     this.trace('remotePeerConnection createAnswer start.');
-    //     this.remotePeerConnection.createAnswer()
-    //         .then(this.createdAnswer)
-    //         .catch(this.setSessionDescriptionError);
 
-    // }
 
-    // createdAnswer = (description: any) => {
-    //     this.trace(`Answer from remotePeerConnection:\n${description.sdp}.`);
+    private maybeStart = () => {
+        console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
+        if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
+            console.log('>>>>>> creating peer connection');
+            this.createPeerConnection();
+            this.pc.addStream(this.localStream);
+            this.isStarted = true;
+            console.log('isInitiator', this.isInitiator);
+            if (this.isInitiator) {
+                this.doCall();
+            }
+        }
+    }
 
-    //     this.trace('remotePeerConnection setLocalDescription start.');
-    //     this.remotePeerConnection.setLocalDescription(description)
-    //         .then(() => {
-    //             this.setLocalDescriptionSuccess(this.remotePeerConnection);
-    //         }).catch(this.setSessionDescriptionError);
 
-    //     this.trace('localPeerConnection setRemoteDescription start.');
-    //     this.localPeerConnection.setRemoteDescription(description)
-    //         .then(() => {
-    //             this.setRemoteDescriptionSuccess(this.localPeerConnection);
-    //         }).catch(this.setSessionDescriptionError);
-    // }
+    // //this will need to be changed to our version of hangUp
+    // window.onbeforeunload = function () {
+    //     sendMessage('bye');
+    // };
+
+    private createPeerConnection = () => {
+        try {
+            this.pc = new RTCPeerConnection(undefined);
+            this.pc.onicecandidate = this.handleIceCandidate;
+            this.pc.onaddstream = this.handleRemoteStreamAdded;
+            this.pc.onremovestream = this.handleRemoteStreamRemoved;
+            console.log('Created RTCPeerConnnection');
+        } catch (e) {
+            console.log('Failed to create PeerConnection, exception: ' + e.message);
+            alert('Cannot create RTCPeerConnection object.');
+            return;
+        }
+    }
 
+    private handleIceCandidate = (event: any) => {
+        console.log('icecandidate event: ', event);
+        if (event.candidate) {
+            this.sendMessage({
+                type: 'candidate',
+                label: event.candidate.sdpMLineIndex,
+                id: event.candidate.sdpMid,
+                candidate: event.candidate.candidate
+            });
+        } else {
+            console.log('End of candidates.');
+        }
+    }
 
-    // startAction = () => {
-    //     this.startButton!.disabled = true;
-    //     navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
-    //         .then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError);
-    //     this.trace('Requesting local stream.');
-    // }
+    private handleCreateOfferError = (event: any) => {
+        console.log('createOffer() error: ', event);
+    }
 
+    private doCall = () => {
+        console.log('Sending offer to peer');
+        this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
+    }
 
-    // // Handles call button action: creates peer connection.
-    // callAction = () => {
-    //     this.callButton!.disabled = true;
-    //     this.hangupButton!.disabled = false;
+    private doAnswer = () => {
+        console.log('Sending answer to peer.');
+        this.pc.createAnswer().then(
+            this.setLocalAndSendMessage,
+            this.onCreateSessionDescriptionError
+        );
+    }
 
-    //     this.trace('Starting call.');
-    //     this.startTime = window.performance.now();
+    private setLocalAndSendMessage = (sessionDescription: any) => {
+        this.pc.setLocalDescription(sessionDescription);
+        console.log('setLocalAndSendMessage sending message', sessionDescription);
+        this.sendMessage(sessionDescription);
+    }
 
-    //     // Get local media stream tracks.
-    //     const videoTracks = this.localStream!.getVideoTracks();
-    //     const audioTracks = this.localStream!.getAudioTracks();
-    //     if (videoTracks.length > 0) {
-    //         this.trace(`Using video device: ${videoTracks[0].label}.`);
-    //     }
-    //     if (audioTracks.length > 0) {
-    //         this.trace(`Using audio device: ${audioTracks[0].label}.`);
-    //     }
+    private onCreateSessionDescriptionError = (error: any) => {
+        console.log('Failed to create session description: ' + error.toString());
+    }
 
-    //     let servers: RTCConfiguration | undefined = undefined;  // Allows for RTC server configuration.
 
-    //     // Create peer connections and add behavior.
-    //     this.localPeerConnection = new RTCPeerConnection(servers);
-    //     this.trace('Created local peer connection object localPeerConnection.');
+    private requestTurn = (turnURL: any) => {
+        var turnExists = false;
+        let self = this;
+        for (var i in this.pcConfig.iceServers) {
+            if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
+                turnExists = true;
+                this.turnReady = true;
+                break;
+            }
+        }
+        if (!turnExists) {
+            console.log('Getting TURN server from ', turnURL);
+            // No TURN server. Get one from computeengineondemand.appspot.com:
+            var xhr = new XMLHttpRequest();
+            xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4 && xhr.status === 200) {
+                    var turnServer = JSON.parse(xhr.responseText);
+                    console.log('Got TURN server: ', turnServer);
+                    self.pcConfig.iceServers.push({
+                        'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
+                        //'credential': turnServer.password
+                    });
+                    self.turnReady = true;
+                }
+            };
+            xhr.open('GET', turnURL, true);
+            xhr.send();
+        }
+    }
 
-    //     this.localPeerConnection.addEventListener('icecandidate', this.handleConnection);
-    //     this.localPeerConnection.addEventListener(
-    //         'iceconnectionstatechange', this.handleConnectionChange);
+    private handleRemoteStreamAdded = (event: MediaStreamEvent) => {
+        console.log('Remote stream added.');
+        this.remoteStream = event.stream!;
+        this.peerVideoEl!.srcObject = this.remoteStream;
+    }
 
-    //     this.remotePeerConnection = new RTCPeerConnection(servers);
-    //     this.trace('Created remote peer connection object remotePeerConnection.');
+    private handleRemoteStreamRemoved = (event: MediaStreamEvent) => {
+        console.log('Remote stream removed. Event: ', event);
+    }
 
-    //     this.remotePeerConnection.addEventListener('icecandidate', this.handleConnection);
-    //     this.remotePeerConnection.addEventListener(
-    //         'iceconnectionstatechange', this.handleConnectionChange);
-    //     this.remotePeerConnection.addEventListener('addstream', this.gotRemoteMediaStream);
+    private hangup = () => {
+        console.log('Hanging up.');
+        if (this.pc) {
+            stop();
+            this.sendMessage('bye');
+        }
 
-    //     // Add local stream to connection and create offer to connect.
-    //     this.localPeerConnection.addStream(this.localStream);
-    //     this.trace('Added local stream to localPeerConnection.');
+        if (this.localStream) {
+            this.localStream.getTracks().forEach(track => track.stop());
+        }
 
-    //     this.trace('localPeerConnection createOffer start.');
-    //     this.localPeerConnection.createOffer(offerOptions)
-    //         .then(this.createdOffer).catch(this.setSessionDescriptionError);
-    // }
+    }
 
+    private handleRemoteHangup = () => {
+        console.log('Session terminated.');
+        stop();
+        this.isInitiator = false;
+    }
 
-    // // Handles hangup action: ends up call, closes connections and resets peers.
-    // hangupAction = () => {
-    //     this.localPeerConnection.close();
-    //     this.remotePeerConnection.close();
-    //     this.localPeerConnection = null;
-    //     this.remotePeerConnection = null;
-    //     this.hangupButton!.disabled = true;
-    //     this.callButton!.disabled = false;
-    //     this.trace('Ending call.');
-    // }
+    private stop = () => {
+        this.isStarted = false;
+        this.pc.close();
+        this.pc = null;
+    }
 
-    // // Gets the "other" peer connection.
-    // getOtherPeer = (peerConnection: any) => {
-    //     return (peerConnection === this.localPeerConnection) ?
-    //         this.remotePeerConnection : this.localPeerConnection;
-    // }
 
-    // // Gets the name of a certain peer connection.
-    // getPeerName = (peerConnection: any) => {
-    //     return (peerConnection === this.localPeerConnection) ?
-    //         'localPeerConnection' : 'remotePeerConnection';
-    // }
 
-    // // Logs an action (text) and the time when it happened on the console.
-    // trace = (text: string) => {
-    //     text = text.trim();
-    //     const now = (window.performance.now() / 1000).toFixed(3);
 
-    //     console.log(now, text);
-    // }
 
 
     /**
       * Function that submits the title entered by user on enter press.
       */
-    onEnterKeyDown = (e: React.KeyboardEvent) => {
+    private onEnterKeyDown = (e: React.KeyboardEvent) => {
         if (e.keyCode === 13) {
             let submittedTitle = this.roomText!.value;
             this.roomText!.value = "";
             this.roomText!.blur();
             this.roomOfCam = submittedTitle;
-            this.webRTCManager!.init(submittedTitle);
+            this.init(submittedTitle);
         }
     }
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebRTCVideo, fieldKey); }
 
 
@@ -365,11 +394,11 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
                 <input type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
                 <video id="localVideo" autoPlay playsInline ref={(e) => {
                     this.localVideoEl = e!;
-                    this.webRTCManager!.setLocalVideoObject(e!);
+                    //this.setLocalVideoObject(e!);
                 }}></video>
                 <video id="remoteVideo" autoPlay playsInline ref={(e) => {
                     this.peerVideoEl = e!;
-                    this.webRTCManager!.setRemoteVideoObject(e!);
+                    //this.setRemoteVideoObject(e!);
                 }}></video>
                 {/* <button id="startButton" ref={(e) => this.startButton = e!} onClick={this.startAction}>Start</button>
                 <button id="callButton" ref={(e) => this.callButton = e!} onClick={this.callAction}>Call</button>
diff --git a/src/server/index.ts b/src/server/index.ts
index 2b18fc578..72ddb5bd7 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -86,51 +86,7 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
         secureHandler: ({ res }) => res.redirect("/home")
     });
 
-    // Utils.AddServerHandler(socket, MessageStore.NotifyRoommates, message => HandleRoommateNotification(socket, message));
-    // // Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message));
-    // // Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin);
 
-    // function HandleRoommateNotification(socket: Socket, message: RoomMessage) {
-    //     //socket.broadcast.emit('message', message);
-    //     console.log("The room that sent this: ", message.room, " and message is : ", message.message);
-    //     server.sockets.in(message.room).emit('message', message);
-
-    // }
-
-    // function HandleCreateOrJoin(socket: io.Socket, room: string) {
-    //     console.log("Received request to create or join room " + room);
-
-
-    //     let clientsInRoom = server.sockets.adapter.rooms[room];
-    //     let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
-    //     console.log('Room ' + room + ' now has ' + numClients + ' client(s)');
-
-
-    //     if (numClients === 0) {
-    //         socket.join(room);
-    //         console.log('Client ID ' + socket.id + ' created room ' + room);
-    //         socket.emit('created', room, socket.id);
-
-    //     } else if (numClients === 1) {
-    //         console.log('Client ID ' + socket.id + ' joined room ' + room);
-    //         server.sockets.in(room).emit('join', room);
-    //         socket.join(room);
-    //         socket.emit('joined', room, socket.id);
-    //         server.sockets.in(room).emit('ready');
-
-    //     } else {
-    //         socket.emit('full', room);
-    //     }
-
-
-
-
-
-    // }
-
-    // function HandleHangUp(socket: io.Socket, message: string) {
-    //     console.log("Receive bye from someone");
-    // }
     addSupervisedRoute({
         method: Method.GET,
         subscription: "/serverHeartbeat",
@@ -165,6 +121,52 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }:
     WebSocket.start(isRelease);
 }
 
+// Utils.AddServerHandler(socket, MessageStore.NotifyRoommates, message => HandleRoommateNotification(socket, message));
+// // Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message));
+// // Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin);
+
+// function HandleRoommateNotification(socket: Socket, message: RoomMessage) {
+//     //socket.broadcast.emit('message', message);
+//     console.log("The room that sent this: ", message.room, " and message is : ", message.message);
+//     server.sockets.in(message.room).emit('message', message);
+
+// }
+
+// function HandleCreateOrJoin(socket: io.Socket, room: string) {
+//     console.log("Received request to create or join room " + room);
+
+
+//     let clientsInRoom = server.sockets.adapter.rooms[room];
+//     let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
+//     console.log('Room ' + room + ' now has ' + numClients + ' client(s)');
+
+
+//     if (numClients === 0) {
+//         socket.join(room);
+//         console.log('Client ID ' + socket.id + ' created room ' + room);
+//         socket.emit('created', room, socket.id);
+
+//     } else if (numClients === 1) {
+//         console.log('Client ID ' + socket.id + ' joined room ' + room);
+//         server.sockets.in(room).emit('join', room);
+//         socket.join(room);
+//         socket.emit('joined', room, socket.id);
+//         server.sockets.in(room).emit('ready');
+
+//     } else {
+//         socket.emit('full', room);
+//     }
+
+
+
+
+
+// }
+
+// function HandleHangUp(socket: io.Socket, message: string) {
+//     console.log("Receive bye from someone");
+// }
+
 /**
  * This function can be used in two different ways. If not in release mode,
  * this is simply the logic that is invoked to start the server. In release mode,
-- 
cgit v1.2.3-70-g09d2


From 9ed82143d9e7c439dc494abfc8825c81b1eabbbf Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Thu, 6 Feb 2020 18:20:43 -0500
Subject: HangUp bug fixed

---
 src/client/views/webcam/DashWebRTCVideo.tsx | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index acba95354..56894c0ac 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -131,7 +131,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
                     candidate: message.message.candidate
                 });
                 self.pc.addIceCandidate(candidate);
-            } else if (message === 'bye' && self.isStarted) {
+            } else if (message.message === 'bye' && self.isStarted) {
                 self.handleRemoteHangup();
             }
         });
@@ -335,8 +335,14 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
 
     private handleRemoteHangup = () => {
         console.log('Session terminated.');
-        stop();
+        this.stop();
         this.isInitiator = false;
+
+        if (this.localStream) {
+            this.localStream.getTracks().forEach(track => track.stop());
+        }
+
+
     }
 
     private stop = () => {
-- 
cgit v1.2.3-70-g09d2


From aa76d4dae61e6fed14b12b778920515b52f616d1 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Fri, 7 Feb 2020 13:21:35 -0500
Subject: added audio

---
 src/client/views/webcam/DashWebRTCVideo.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 56894c0ac..4c75b76c9 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -137,7 +137,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
         });
 
         navigator.mediaDevices.getUserMedia({
-            audio: false,
+            audio: true,
             video: true
         })
             .then(this.gotStream)
-- 
cgit v1.2.3-70-g09d2


From 2f04ee2c5d24aa4df9860414a7b5a7f990ecfa12 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Fri, 7 Feb 2020 13:35:18 -0500
Subject: Some css

---
 src/client/views/webcam/DashWebRTCVideo.scss | 36 ++++++++++++++++++++++++++++
 src/client/views/webcam/DashWebRTCVideo.tsx  |  9 +++----
 2 files changed, 39 insertions(+), 6 deletions(-)
 create mode 100644 src/client/views/webcam/DashWebRTCVideo.scss

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
new file mode 100644
index 000000000..30665e849
--- /dev/null
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -0,0 +1,36 @@
+@import "../globalCssVariables";
+
+.webcam-cont {
+    // position: absolute;
+    background: whitesmoke;
+    color: grey;
+    border-radius: 15px;
+    box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
+    border: solid #BBBBBBBB 5px;
+    pointer-events: all;
+
+    .webcam-header {
+        height: 50px;
+        text-align: center;
+        text-transform: uppercase;
+        letter-spacing: 2px;
+        font-size: 16px;
+        width: 100%;
+    }
+
+    #localVideo {
+        margin: 10px;
+        position: relative;
+        width: 300px;
+        max-height: 300px;
+    }
+
+    #remoteVideo {
+        margin: 10px;
+        position: relative;
+        width: 300px;
+        max-height: 300px;
+
+    }
+
+}
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 4c75b76c9..0b704db66 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -6,7 +6,7 @@ import { observable } from "mobx";
 import { DocumentDecorations, CloseCall } from "../DocumentDecorations";
 import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
-import "./DashWebRTC.scss";
+import "./DashWebRTCVideo.scss";
 import adapter from 'webrtc-adapter';
 import { DocServer } from "../../DocServer";
 import { DocumentView } from "../nodes/DocumentView";
@@ -397,18 +397,15 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     render() {
         let content =
             <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+                <div className="webcam-header">DashWebRTC</div>
                 <input type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
                 <video id="localVideo" autoPlay playsInline ref={(e) => {
                     this.localVideoEl = e!;
-                    //this.setLocalVideoObject(e!);
                 }}></video>
                 <video id="remoteVideo" autoPlay playsInline ref={(e) => {
                     this.peerVideoEl = e!;
-                    //this.setRemoteVideoObject(e!);
                 }}></video>
-                {/* <button id="startButton" ref={(e) => this.startButton = e!} onClick={this.startAction}>Start</button>
-                <button id="callButton" ref={(e) => this.callButton = e!} onClick={this.callAction}>Call</button>
-                <button id="hangupButton" ref={(e) => this.hangupButton = e!} onClick={this.hangupAction}>Hang Up</button> */}
+
             </div>;
 
         let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
-- 
cgit v1.2.3-70-g09d2


From ce5980ddf7cdd247f8e31be1c437b9c40d46e29d Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Fri, 7 Feb 2020 19:48:38 -0500
Subject: More ui work done

---
 src/client/views/webcam/DashWebRTCVideo.scss | 49 ++++++++++++++++++++++------
 src/client/views/webcam/DashWebRTCVideo.tsx  | 14 ++++----
 2 files changed, 47 insertions(+), 16 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
index 30665e849..ccb0a626b 100644
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -8,6 +8,9 @@
     box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
     border: solid #BBBBBBBB 5px;
     pointer-events: all;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
 
     .webcam-header {
         height: 50px;
@@ -18,19 +21,45 @@
         width: 100%;
     }
 
-    #localVideo {
-        margin: 10px;
-        position: relative;
-        width: 300px;
-        max-height: 300px;
+    #roomName {
+        outline: none;
+        border-radius: inherit;
+        border: 1px solid #BBBBBBBB;
     }
 
-    #remoteVideo {
-        margin: 10px;
-        position: relative;
-        width: 300px;
-        max-height: 300px;
+    // #localVideo {
+    //     width: 25%;
+    //     height: 20%;
+    //     position: absolute;
+    //     top: 65%;
+    //     z-index: 2;
+    //     right: 5%;
+    // }
 
+    .side {
+        width: 25%;
+        height: 20%;
+        position: absolute;
+        top: 65%;
+        z-index: 2;
+        right: 5%;
     }
 
+    .main {
+        position: absolute;
+        width: 95%;
+        height: 75%;
+        top: 20%;
+        align-self: center;
+    }
+
+    // #remoteVideo {
+    //     position: absolute;
+    //     width: 95%;
+    //     height: 75%;
+    //     top: 20%;
+    //     align-self: center;
+
+    // }
+
 }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 0b704db66..290ca7a48 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -2,7 +2,7 @@ import { observer } from "mobx-react";
 import React = require("react");
 import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView";
 import { FieldViewProps, FieldView } from "../nodes/FieldView";
-import { observable } from "mobx";
+import { observable, action } from "mobx";
 import { DocumentDecorations, CloseCall } from "../DocumentDecorations";
 import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
@@ -38,6 +38,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private isChannelReady = false;
     private isInitiator = false;
     private isStarted = false;
+    @observable remoteVideoAdded: boolean = false;
     localStream: MediaStream | undefined;
     private pc: any;
     remoteStream: MediaStream | undefined;
@@ -309,11 +310,12 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
             xhr.send();
         }
     }
-
+    @action
     private handleRemoteStreamAdded = (event: MediaStreamEvent) => {
         console.log('Remote stream added.');
         this.remoteStream = event.stream!;
         this.peerVideoEl!.srcObject = this.remoteStream;
+        this.remoteVideoAdded = true;
     }
 
     private handleRemoteStreamRemoved = (event: MediaStreamEvent) => {
@@ -398,15 +400,15 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
         let content =
             <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 <div className="webcam-header">DashWebRTC</div>
-                <input type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
-                <video id="localVideo" autoPlay playsInline ref={(e) => {
+                <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
+                <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline ref={(e) => {
                     this.localVideoEl = e!;
                 }}></video>
-                <video id="remoteVideo" autoPlay playsInline ref={(e) => {
+                <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
                     this.peerVideoEl = e!;
                 }}></video>
 
-            </div>;
+            </div >;
 
         let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
         let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
-- 
cgit v1.2.3-70-g09d2


From d3db291c2587bf1284f9d0a8ee7d06fd8ec7a252 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Fri, 7 Feb 2020 21:52:49 -0500
Subject: Another refactor with modules

---
 src/client/views/webcam/DashWebRTCVideo.scss |  31 +-
 src/client/views/webcam/DashWebRTCVideo.tsx  | 575 +++++++++++++--------------
 src/client/views/webcam/WebCamLogic.js       | 268 +++++++++++++
 src/server/Websocket/Websocket.ts            |  51 ++-
 4 files changed, 607 insertions(+), 318 deletions(-)
 create mode 100644 src/client/views/webcam/WebCamLogic.js

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
index ccb0a626b..262528d8e 100644
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -27,14 +27,14 @@
         border: 1px solid #BBBBBBBB;
     }
 
-    // #localVideo {
-    //     width: 25%;
-    //     height: 20%;
-    //     position: absolute;
-    //     top: 65%;
-    //     z-index: 2;
-    //     right: 5%;
-    // }
+    #localVideo {
+        width: 50%;
+        height: 50%;
+        position: relative;
+        // top: 65%;
+        // z-index: 2;
+        // right: 5%;
+    }
 
     .side {
         width: 25%;
@@ -53,13 +53,12 @@
         align-self: center;
     }
 
-    // #remoteVideo {
-    //     position: absolute;
-    //     width: 95%;
-    //     height: 75%;
-    //     top: 20%;
-    //     align-self: center;
-
-    // }
+    #remoteVideo {
+        position: relative;
+        width: 50%;
+        height: 50%;
+        // top: 20%;
+        // align-self: center;
+    }
 
 }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 290ca7a48..191f5750d 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -12,9 +12,7 @@ import { DocServer } from "../../DocServer";
 import { DocumentView } from "../nodes/DocumentView";
 import { Utils } from "../../../Utils";
 import { MessageStore } from "../../../server/Message";
-
-
-
+import { initialize } from "./WebCamLogic";
 
 const mediaStreamConstraints = {
     video: true,
@@ -24,358 +22,335 @@ const offerOptions = {
     offerToReceiveVideo: 1,
 };
 
-
 /**
  * This models the component that will be rendered, that can be used as a doc that will reflect the video cams.
  */
 @observer
 export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentViewProps & FieldViewProps> {
-
     @observable private localVideoEl: HTMLVideoElement | undefined;
     @observable private peerVideoEl: HTMLVideoElement | undefined;
-    private roomText: HTMLInputElement | undefined;
-    private roomOfCam: string = "";
-    private isChannelReady = false;
-    private isInitiator = false;
-    private isStarted = false;
-    @observable remoteVideoAdded: boolean = false;
-    localStream: MediaStream | undefined;
-    private pc: any;
-    remoteStream: MediaStream | undefined;
-    private turnReady: boolean | undefined;
-    //localVideo: HTMLVideoElement | undefined;
-    //remoteVideo: HTMLVideoElement | undefined;
-    curRoom: string = "";
-
-
-    private pcConfig = {
-        'iceServers': [{
-            'urls': 'stun:stun.l.google.com:19302'
-        }]
-    };
-
-    // Set up audio and video regardless of what devices are present.
-    private sdpConstraints = {
-        offerToReceiveAudio: true,
-        offerToReceiveVideo: true
-    };
+    // private roomText: HTMLInputElement | undefined;
+    // private roomOfCam: string = "";
+    // private isChannelReady = false;
+    // private isInitiator = false;
+    // private isStarted = false;
+    // @observable remoteVideoAdded: boolean = false;
+    // localStream: MediaStream | undefined;
+    // private pc: any;
+    // remoteStream: MediaStream | undefined;
+    // private turnReady: boolean | undefined;
+    // //localVideo: HTMLVideoElement | undefined;
+    // //remoteVideo: HTMLVideoElement | undefined;
+    // curRoom: string = "";
+
+    // private pcConfig = {
+    //     'iceServers': [{
+    //         'urls': 'stun:stun.l.google.com:19302'
+    //     }]
+    // };
+
+    // // Set up audio and video regardless of what devices are present.
+    // private sdpConstraints = {
+    //     offerToReceiveAudio: true,
+    //     offerToReceiveVideo: true
+    // };
 
     componentDidMount() {
-        DocumentDecorations.Instance.addCloseCall(this.closeConnection);
-        let self = this;
-        window.onbeforeunload = function () {
-            self.sendMessage('bye');
-        };
+        // DocumentDecorations.Instance.addCloseCall(this.closeConnection);
+        setTimeout(() => initialize(), 10000);
+        // let self = this;
+        // window.onbeforeunload = function () {
+        //     self.sendMessage('bye');
+        // };
     }
 
-    closeConnection: CloseCall = () => {
-        this.hangup();
-    }
+    // closeConnection: CloseCall = () => {
+    //     this.hangup();
+    // }
 
-    componentWillUnmount() {
-    }
+    // componentWillUnmount() {
+    // }
 
 
-    init(room: string) {
+    // init(room: string) {
+
+    //     this.curRoom = room;
+    //     let self = this;
+
+    //     if (room !== '') {
+    //         DocServer._socket.emit('create or join', room);
+    //         console.log('Attempted to create or  join room', room);
+
+    //     }
+
+    //     DocServer._socket.on('created', function (room: string) {
+    //         console.log('Created room ' + room);
+    //         self.isInitiator = true;
+    //     });
+
+    //     DocServer._socket.on('full', function (room: string) {
+    //         console.log('Room ' + room + ' is full');
+    //     });
+
+    //     DocServer._socket.on('join', function (room: string) {
+    //         console.log('Another peer made a request to join room ' + room);
+    //         console.log('This peer is the initiator of room ' + room + '!');
+    //         self.isChannelReady = true;
+    //     });
+
+
+    //     DocServer._socket.on('joined', function (room: string) {
+    //         console.log('joined: ' + room);
+    //         self.isChannelReady = true;
+    //     });
+
+
+    //     DocServer._socket.on('log', function (array: any) {
+    //         console.log.apply(console, array);
+    //     });
+
+    //     // This client receives a message
+    //     DocServer._socket.on('message', async function (message: any) {
+    //         console.log('Client received message:', message);
+    //         if (message.message === 'got user media') {
+    //             self.maybeStart();
+    //         } else if (message.message.type === 'offer') {
+    //             if (!self.isInitiator && !self.isStarted) {
+    //                 self.maybeStart();
+    //             }
+    //             await self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+    //             self.doAnswer();
+    //         } else if (message.message.type === 'answer' && self.isStarted) {
+    //             await self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+    //         } else if (message.message.type === 'candidate' && self.isStarted) {
+    //             let candidate = new RTCIceCandidate({
+    //                 sdpMLineIndex: message.message.label,
+    //                 candidate: message.message.candidate
+    //             });
+    //             self.pc.addIceCandidate(candidate);
+    //         } else if (message.message === 'bye' && self.isStarted) {
+    //             self.handleRemoteHangup();
+    //         }
+    //     });
+
+    //     navigator.mediaDevices.getUserMedia({
+    //         audio: true,
+    //         video: true
+    //     })
+    //         .then(this.gotStream)
+    //         .catch(function (e) {
+    //             alert('getUserMedia() error: ' + e.name);
+    //         });
+
+    //     //Trying this one out!!!
+    //     console.log('Getting user media with constraints', this.constraints);
+
+    //     if (location.hostname !== 'localhost') {
+    //         this.requestTurn(
+    //             'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
+    //         );
+    //     }
 
-        this.curRoom = room;
-        let self = this;
 
-        if (room !== '') {
-            DocServer._socket.emit('create or join', room);
-            console.log('Attempted to create or  join room', room);
+    // }
 
-        }
 
-        DocServer._socket.on('created', function (room: string) {
-            console.log('Created room ' + room);
-            self.isInitiator = true;
-        });
-
-        DocServer._socket.on('full', function (room: string) {
-            console.log('Room ' + room + ' is full');
-        });
-
-        DocServer._socket.on('join', function (room: string) {
-            console.log('Another peer made a request to join room ' + room);
-            console.log('This peer is the initiator of room ' + room + '!');
-            self.isChannelReady = true;
-        });
-
-
-        DocServer._socket.on('joined', function (room: string) {
-            console.log('joined: ' + room);
-            self.isChannelReady = true;
-        });
-
-
-        DocServer._socket.on('log', function (array: any) {
-            console.log.apply(console, array);
-        });
-
-        // This client receives a message
-        DocServer._socket.on('message', function (message: any) {
-            console.log('Client received message:', message);
-            if (message.message === 'got user media') {
-                self.maybeStart();
-            } else if (message.message.type === 'offer') {
-                if (!self.isInitiator && !self.isStarted) {
-                    self.maybeStart();
-                }
-                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-                self.doAnswer();
-            } else if (message.message.type === 'answer' && self.isStarted) {
-                self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-            } else if (message.message.type === 'candidate' && self.isStarted) {
-                let candidate = new RTCIceCandidate({
-                    sdpMLineIndex: message.message.label,
-                    candidate: message.message.candidate
-                });
-                self.pc.addIceCandidate(candidate);
-            } else if (message.message === 'bye' && self.isStarted) {
-                self.handleRemoteHangup();
-            }
-        });
-
-        navigator.mediaDevices.getUserMedia({
-            audio: true,
-            video: true
-        })
-            .then(this.gotStream)
-            .catch(function (e) {
-                alert('getUserMedia() error: ' + e.name);
-            });
-
-        //Trying this one out!!!
-        console.log('Getting user media with constraints', this.constraints);
-
-        if (location.hostname !== 'localhost') {
-            this.requestTurn(
-                'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
-            );
-        }
+    // private sendMessage = (message: any) => {
+    //     console.log('Client sending message: ', message);
+    //     Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
+    //     //DocServer._socket.emit('message', message);
+    // }
 
 
-    }
 
+    // private gotStream = (stream: any) => {
+    //     console.log('Adding local stream.');
+    //     this.localStream = stream;
+    //     this.localVideoEl!.srcObject = stream;
+    //     this.sendMessage('got user media');
+    //     if (this.isInitiator) {
+    //         this.maybeStart();
+    //     }
+    // }
 
-    private sendMessage = (message: any) => {
-        console.log('Client sending message: ', message);
-        Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
-        //DocServer._socket.emit('message', message);
-    }
+    // constraints = {
+    //     video: true,
+    //     audio: true
+    // };
 
 
 
 
 
-    // setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
-    //     this.localVideo = localVideo;
-    //     this.remoteVideo = remoteVideo;
+    // private maybeStart = () => {
+    //     console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
+    //     if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
+    //         console.log('>>>>>> creating peer connection');
+    //         this.createPeerConnection();
+    //         this.pc.addStream(this.localStream);
+    //         this.isStarted = true;
+    //         console.log('isInitiator', this.isInitiator);
+    //         if (this.isInitiator) {
+    //             this.doCall();
+    //         }
+    //     }
     // }
 
-    // setLocalVideoObject(localVideoRef: HTMLVideoElement) {
-    //     this.localVideo = localVideoRef;
 
+    // // //this will need to be changed to our version of hangUp
+    // // window.onbeforeunload = function () {
+    // //     sendMessage('bye');
+    // // };
+
+    // private createPeerConnection = () => {
+    //     try {
+    //         this.pc = new RTCPeerConnection(undefined);
+    //         this.pc.onicecandidate = this.handleIceCandidate;
+    //         this.pc.onaddstream = this.handleRemoteStreamAdded;
+    //         this.pc.onremovestream = this.handleRemoteStreamRemoved;
+    //         console.log('Created RTCPeerConnnection');
+    //     } catch (e) {
+    //         console.log('Failed to create PeerConnection, exception: ' + e.message);
+    //         alert('Cannot create RTCPeerConnection object.');
+    //         return;
+    //     }
     // }
 
-    // setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
-    //     this.remoteVideo = remoteVideoRef;
+    // private handleIceCandidate = (event: any) => {
+    //     console.log('icecandidate event: ', event);
+    //     if (event.candidate) {
+    //         this.sendMessage({
+    //             type: 'candidate',
+    //             label: event.candidate.sdpMLineIndex,
+    //             id: event.candidate.sdpMid,
+    //             candidate: event.candidate.candidate
+    //         });
+    //     } else {
+    //         console.log('End of candidates.');
+    //     }
     // }
 
+    // private handleCreateOfferError = (event: any) => {
+    //     console.log('createOffer() error: ', event);
+    // }
 
+    // private doCall = () => {
+    //     console.log('Sending offer to peer');
+    //     this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
+    // }
 
+    // private doAnswer = () => {
+    //     console.log('Sending answer to peer.');
+    //     this.pc.createAnswer().then(
+    //         this.setLocalAndSendMessage,
+    //         this.onCreateSessionDescriptionError
+    //     );
+    // }
 
-    private gotStream = (stream: any) => {
-        console.log('Adding local stream.');
-        this.localStream = stream;
-        this.localVideoEl!.srcObject = stream;
-        this.sendMessage('got user media');
-        if (this.isInitiator) {
-            this.maybeStart();
-        }
-    }
-
-    constraints = {
-        video: true,
-        audio: true
-    };
-
-
-
-
-
-    private maybeStart = () => {
-        console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
-        if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
-            console.log('>>>>>> creating peer connection');
-            this.createPeerConnection();
-            this.pc.addStream(this.localStream);
-            this.isStarted = true;
-            console.log('isInitiator', this.isInitiator);
-            if (this.isInitiator) {
-                this.doCall();
-            }
-        }
-    }
-
-
-    // //this will need to be changed to our version of hangUp
-    // window.onbeforeunload = function () {
-    //     sendMessage('bye');
-    // };
-
-    private createPeerConnection = () => {
-        try {
-            this.pc = new RTCPeerConnection(undefined);
-            this.pc.onicecandidate = this.handleIceCandidate;
-            this.pc.onaddstream = this.handleRemoteStreamAdded;
-            this.pc.onremovestream = this.handleRemoteStreamRemoved;
-            console.log('Created RTCPeerConnnection');
-        } catch (e) {
-            console.log('Failed to create PeerConnection, exception: ' + e.message);
-            alert('Cannot create RTCPeerConnection object.');
-            return;
-        }
-    }
-
-    private handleIceCandidate = (event: any) => {
-        console.log('icecandidate event: ', event);
-        if (event.candidate) {
-            this.sendMessage({
-                type: 'candidate',
-                label: event.candidate.sdpMLineIndex,
-                id: event.candidate.sdpMid,
-                candidate: event.candidate.candidate
-            });
-        } else {
-            console.log('End of candidates.');
-        }
-    }
-
-    private handleCreateOfferError = (event: any) => {
-        console.log('createOffer() error: ', event);
-    }
-
-    private doCall = () => {
-        console.log('Sending offer to peer');
-        this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
-    }
-
-    private doAnswer = () => {
-        console.log('Sending answer to peer.');
-        this.pc.createAnswer().then(
-            this.setLocalAndSendMessage,
-            this.onCreateSessionDescriptionError
-        );
-    }
-
-    private setLocalAndSendMessage = (sessionDescription: any) => {
-        this.pc.setLocalDescription(sessionDescription);
-        console.log('setLocalAndSendMessage sending message', sessionDescription);
-        this.sendMessage(sessionDescription);
-    }
+    // private setLocalAndSendMessage = (sessionDescription: any) => {
+    //     this.pc.setLocalDescription(sessionDescription);
+    //     console.log('setLocalAndSendMessage sending message', sessionDescription);
+    //     this.sendMessage(sessionDescription);
+    // }
 
-    private onCreateSessionDescriptionError = (error: any) => {
-        console.log('Failed to create session description: ' + error.toString());
-    }
+    // private onCreateSessionDescriptionError = (error: any) => {
+    //     console.log('Failed to create session description: ' + error.toString());
+    // }
 
 
-    private requestTurn = (turnURL: any) => {
-        var turnExists = false;
-        let self = this;
-        for (var i in this.pcConfig.iceServers) {
-            if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
-                turnExists = true;
-                this.turnReady = true;
-                break;
-            }
-        }
-        if (!turnExists) {
-            console.log('Getting TURN server from ', turnURL);
-            // No TURN server. Get one from computeengineondemand.appspot.com:
-            var xhr = new XMLHttpRequest();
-            xhr.onreadystatechange = function () {
-                if (xhr.readyState === 4 && xhr.status === 200) {
-                    var turnServer = JSON.parse(xhr.responseText);
-                    console.log('Got TURN server: ', turnServer);
-                    self.pcConfig.iceServers.push({
-                        'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
-                        //'credential': turnServer.password
-                    });
-                    self.turnReady = true;
-                }
-            };
-            xhr.open('GET', turnURL, true);
-            xhr.send();
-        }
-    }
-    @action
-    private handleRemoteStreamAdded = (event: MediaStreamEvent) => {
-        console.log('Remote stream added.');
-        this.remoteStream = event.stream!;
-        this.peerVideoEl!.srcObject = this.remoteStream;
-        this.remoteVideoAdded = true;
-    }
+    // private requestTurn = (turnURL: any) => {
+    //     var turnExists = false;
+    //     let self = this;
+    //     for (var i in this.pcConfig.iceServers) {
+    //         if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
+    //             turnExists = true;
+    //             this.turnReady = true;
+    //             break;
+    //         }
+    //     }
+    //     if (!turnExists) {
+    //         console.log('Getting TURN server from ', turnURL);
+    //         // No TURN server. Get one from computeengineondemand.appspot.com:
+    //         var xhr = new XMLHttpRequest();
+    //         xhr.onreadystatechange = function () {
+    //             if (xhr.readyState === 4 && xhr.status === 200) {
+    //                 var turnServer = JSON.parse(xhr.responseText);
+    //                 console.log('Got TURN server: ', turnServer);
+    //                 self.pcConfig.iceServers.push({
+    //                     'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
+    //                     //'credential': turnServer.password
+    //                 });
+    //                 self.turnReady = true;
+    //             }
+    //         };
+    //         xhr.open('GET', turnURL, true);
+    //         xhr.send();
+    //     }
+    // }
+    // @action
+    // private handleRemoteStreamAdded = (event: MediaStreamEvent) => {
+    //     console.log('Remote stream added.');
+    //     this.remoteStream = event.stream!;
+    //     this.peerVideoEl!.srcObject = this.remoteStream;
+    //     this.remoteVideoAdded = true;
+    // }
 
-    private handleRemoteStreamRemoved = (event: MediaStreamEvent) => {
-        console.log('Remote stream removed. Event: ', event);
-    }
+    // private handleRemoteStreamRemoved = (event: MediaStreamEvent) => {
+    //     console.log('Remote stream removed. Event: ', event);
+    // }
 
-    private hangup = () => {
-        console.log('Hanging up.');
-        if (this.pc) {
-            stop();
-            this.sendMessage('bye');
-        }
+    // private hangup = () => {
+    //     console.log('Hanging up.');
+    //     if (this.pc) {
+    //         stop();
+    //         this.sendMessage('bye');
+    //     }
 
-        if (this.localStream) {
-            this.localStream.getTracks().forEach(track => track.stop());
-        }
+    //     if (this.localStream) {
+    //         this.localStream.getTracks().forEach(track => track.stop());
+    //     }
 
-    }
+    // }
 
-    private handleRemoteHangup = () => {
-        console.log('Session terminated.');
-        this.stop();
-        this.isInitiator = false;
+    // private handleRemoteHangup = () => {
+    //     console.log('Session terminated.');
+    //     this.stop();
+    //     this.isInitiator = false;
 
-        if (this.localStream) {
-            this.localStream.getTracks().forEach(track => track.stop());
-        }
+    //     if (this.localStream) {
+    //         this.localStream.getTracks().forEach(track => track.stop());
+    //     }
 
 
-    }
+    // }
 
-    private stop = () => {
-        this.isStarted = false;
-        this.pc.close();
-        this.pc = null;
-    }
+    // private stop = () => {
+    //     this.isStarted = false;
+    //     this.pc.close();
+    //     this.pc = null;
+    // }
 
 
 
 
 
 
-    /**
-      * Function that submits the title entered by user on enter press.
-      */
-    private onEnterKeyDown = (e: React.KeyboardEvent) => {
-        if (e.keyCode === 13) {
-            let submittedTitle = this.roomText!.value;
-            this.roomText!.value = "";
-            this.roomText!.blur();
-            this.roomOfCam = submittedTitle;
-            this.init(submittedTitle);
-        }
-    }
+    // /**
+    //   * Function that submits the title entered by user on enter press.
+    //   */
+    // private onEnterKeyDown = (e: React.KeyboardEvent) => {
+    //     if (e.keyCode === 13) {
+    //         let submittedTitle = this.roomText!.value;
+    //         this.roomText!.value = "";
+    //         this.roomText!.blur();
+    //         this.roomOfCam = submittedTitle;
+    //         this.init(submittedTitle);
+    //     }
+    // }
 
 
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebRTCVideo, fieldKey); }
 
-
-
     _ignore = 0;
     onPreWheel = (e: React.WheelEvent) => {
         this._ignore = e.timeStamp;
@@ -394,17 +369,15 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
         }
     }
 
-
-
     render() {
         let content =
             <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 <div className="webcam-header">DashWebRTC</div>
-                <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
-                <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline ref={(e) => {
+                {/* <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} /> */}
+                <video id="localVideo" autoPlay playsInline ref={(e) => {
                     this.localVideoEl = e!;
                 }}></video>
-                <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
+                <video id="remoteVideo" autoPlay playsInline ref={(e) => {
                     this.peerVideoEl = e!;
                 }}></video>
 
diff --git a/src/client/views/webcam/WebCamLogic.js b/src/client/views/webcam/WebCamLogic.js
new file mode 100644
index 000000000..d4798f72f
--- /dev/null
+++ b/src/client/views/webcam/WebCamLogic.js
@@ -0,0 +1,268 @@
+'use strict';
+import io from "socket.io-client";
+
+export function initialize() {
+
+    var isChannelReady = false;
+    var isInitiator = false;
+    var isStarted = false;
+    var localStream;
+    var pc;
+    var remoteStream;
+    var turnReady;
+
+    var pcConfig = {
+        'iceServers': [{
+            'urls': 'stun:stun.l.google.com:19302'
+        }]
+    };
+
+    // Set up audio and video regardless of what devices are present.
+    var sdpConstraints = {
+        offerToReceiveAudio: true,
+        offerToReceiveVideo: true
+    };
+
+    /////////////////////////////////////////////
+
+    var room = 'foo';
+    // Could prompt for room name:
+    // room = prompt('Enter room name:');
+
+    var socket = io.connect(`${window.location.protocol}//${window.location.hostname}:${4321}`);
+
+    if (room !== '') {
+        socket.emit('create or join', room);
+        console.log('Attempted to create or  join room', room);
+    }
+
+    socket.on('created', function (room) {
+        console.log('Created room ' + room);
+        isInitiator = true;
+    });
+
+    socket.on('full', function (room) {
+        console.log('Room ' + room + ' is full');
+    });
+
+    socket.on('join', function (room) {
+        console.log('Another peer made a request to join room ' + room);
+        console.log('This peer is the initiator of room ' + room + '!');
+        isChannelReady = true;
+    });
+
+    socket.on('joined', function (room) {
+        console.log('joined: ' + room);
+        isChannelReady = true;
+    });
+
+    socket.on('log', function (array) {
+        console.log.apply(console, array);
+    });
+
+    ////////////////////////////////////////////////
+
+    const sendMessage = (message) => {
+        console.log('Client sending message: ', message);
+        socket.emit('message', message);
+    };
+
+    // This client receives a message
+    socket.on('message', function (message) {
+        console.log('Client received message:', message);
+        if (message === 'got user media') {
+            maybeStart();
+        } else if (message.type === 'offer') {
+            if (!isInitiator && !isStarted) {
+                maybeStart();
+            }
+            pc.setRemoteDescription(new RTCSessionDescription(message));
+            doAnswer();
+        } else if (message.type === 'answer' && isStarted) {
+            pc.setRemoteDescription(new RTCSessionDescription(message));
+        } else if (message.type === 'candidate' && isStarted) {
+            var candidate = new RTCIceCandidate({
+                sdpMLineIndex: message.label,
+                candidate: message.candidate
+            });
+            pc.addIceCandidate(candidate);
+        } else if (message === 'bye' && isStarted) {
+            handleRemoteHangup();
+        }
+    });
+
+    ////////////////////////////////////////////////////
+
+    var localVideo = document.querySelector('#localVideo');
+    var remoteVideo = document.querySelector('#remoteVideo');
+
+    console.log("Local Video: ", localVideo);
+    console.log("Remote Video: ", remoteVideo);
+
+    const gotStream = (stream) => {
+        console.log('Adding local stream.');
+        localStream = stream;
+        localVideo.srcObject = stream;
+        sendMessage('got user media');
+        if (isInitiator) {
+            maybeStart();
+        }
+    }
+
+
+    navigator.mediaDevices.getUserMedia({
+        audio: false,
+        video: true
+    })
+        .then(gotStream)
+        .catch(function (e) {
+            alert('getUserMedia() error: ' + e.name);
+        });
+
+
+
+    var constraints = {
+        video: true
+    };
+
+    console.log('Getting user media with constraints', constraints);
+
+    if (location.hostname !== 'localhost') {
+        requestTurn(
+            'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
+        );
+    }
+
+    const maybeStart = () => {
+        console.log('>>>>>>> maybeStart() ', isStarted, localStream, isChannelReady);
+        if (!isStarted && typeof localStream !== 'undefined' && isChannelReady) {
+            console.log('>>>>>> creating peer connection');
+            createPeerConnection();
+            pc.addStream(localStream);
+            isStarted = true;
+            console.log('isInitiator', isInitiator);
+            if (isInitiator) {
+                doCall();
+            }
+        }
+    };
+
+    window.onbeforeunload = function () {
+        sendMessage('bye');
+    };
+
+    /////////////////////////////////////////////////////////
+
+    const createPeerConnection = () => {
+        try {
+            pc = new RTCPeerConnection(null);
+            pc.onicecandidate = handleIceCandidate;
+            pc.onaddstream = handleRemoteStreamAdded;
+            pc.onremovestream = handleRemoteStreamRemoved;
+            console.log('Created RTCPeerConnnection');
+        } catch (e) {
+            console.log('Failed to create PeerConnection, exception: ' + e.message);
+            alert('Cannot create RTCPeerConnection object.');
+            return;
+        }
+    }
+
+    const handleIceCandidate = (event) => {
+        console.log('icecandidate event: ', event);
+        if (event.candidate) {
+            sendMessage({
+                type: 'candidate',
+                label: event.candidate.sdpMLineIndex,
+                id: event.candidate.sdpMid,
+                candidate: event.candidate.candidate
+            });
+        } else {
+            console.log('End of candidates.');
+        }
+    }
+
+    const handleCreateOfferError = (event) => {
+        console.log('createOffer() error: ', event);
+    }
+
+    const doCall = () => {
+        console.log('Sending offer to peer');
+        pc.createOffer(setLocalAndSendMessage, handleCreateOfferError);
+    }
+
+    const doAnswer = () => {
+        console.log('Sending answer to peer.');
+        pc.createAnswer().then(
+            setLocalAndSendMessage,
+            onCreateSessionDescriptionError
+        );
+    }
+
+    const setLocalAndSendMessage = (sessionDescription) => {
+        pc.setLocalDescription(sessionDescription);
+        console.log('setLocalAndSendMessage sending message', sessionDescription);
+        sendMessage(sessionDescription);
+    }
+
+    const onCreateSessionDescriptionError = (error) => {
+        trace('Failed to create session description: ' + error.toString());
+    }
+
+    const requestTurn = (turnURL) => {
+        var turnExists = false;
+        for (var i in pcConfig.iceServers) {
+            if (pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
+                turnExists = true;
+                turnReady = true;
+                break;
+            }
+        }
+        if (!turnExists) {
+            console.log('Getting TURN server from ', turnURL);
+            // No TURN server. Get one from computeengineondemand.appspot.com:
+            var xhr = new XMLHttpRequest();
+            xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4 && xhr.status === 200) {
+                    var turnServer = JSON.parse(xhr.responseText);
+                    console.log('Got TURN server: ', turnServer);
+                    pcConfig.iceServers.push({
+                        'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
+                        'credential': turnServer.password
+                    });
+                    turnReady = true;
+                }
+            };
+            xhr.open('GET', turnURL, true);
+            xhr.send();
+        }
+    }
+
+    const handleRemoteStreamAdded = (event) => {
+        console.log('Remote stream added.');
+        remoteStream = event.stream;
+        remoteVideo.srcObject = remoteStream;
+    };
+
+    const handleRemoteStreamRemoved = (event) => {
+        console.log('Remote stream removed. Event: ', event);
+    }
+
+    const hangup = () => {
+        console.log('Hanging up.');
+        stop();
+        sendMessage('bye');
+    }
+
+    const handleRemoteHangup = () => {
+        console.log('Session terminated.');
+        stop();
+        isInitiator = false;
+    }
+
+    const stop = () => {
+        isStarted = false;
+        pc.close();
+        pc = null;
+    }
+
+}
\ No newline at end of file
diff --git a/src/server/Websocket/Websocket.ts b/src/server/Websocket/Websocket.ts
index ff208d917..96694bf72 100644
--- a/src/server/Websocket/Websocket.ts
+++ b/src/server/Websocket/Websocket.ts
@@ -10,6 +10,7 @@ import { GoogleCredentialsLoader } from "../credentials/CredentialsLoader";
 import { logPort } from "../ActionUtilities";
 import { timeMap } from "../ApiManagers/UserManager";
 import { green } from "colors";
+import { networkInterfaces } from "os";
 
 export namespace WebSocket {
 
@@ -40,6 +41,55 @@ export namespace WebSocket {
                 next();
             });
 
+            // convenience function to log server messages on the client
+            function log(message?: any, ...optionalParams: any[]) {
+                socket.emit('log', ['Message from server:', message, ...optionalParams]);
+            }
+
+            socket.on('message', function (message) {
+                log('Client said: ', message);
+                // for a real app, would be room-only (not broadcast)
+                socket.broadcast.emit('message', message);
+            });
+
+            socket.on('create or join', function (room) {
+                log('Received request to create or join room ' + room);
+
+                var clientsInRoom = socket.adapter.rooms[room];
+                var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
+                log('Room ' + room + ' now has ' + numClients + ' client(s)');
+
+                if (numClients === 0) {
+                    socket.join(room);
+                    log('Client ID ' + socket.id + ' created room ' + room);
+                    socket.emit('created', room, socket.id);
+
+                } else if (numClients === 1) {
+                    log('Client ID ' + socket.id + ' joined room ' + room);
+                    socket.in(room).emit('join', room);
+                    socket.join(room);
+                    socket.emit('joined', room, socket.id);
+                    socket.in(room).emit('ready');
+                } else { // max two clients
+                    socket.emit('full', room);
+                }
+            });
+
+            socket.on('ipaddr', function () {
+                var ifaces = networkInterfaces();
+                for (var dev in ifaces) {
+                    ifaces[dev].forEach(function (details) {
+                        if (details.family === 'IPv4' && details.address !== '127.0.0.1') {
+                            socket.emit('ipaddr', details.address);
+                        }
+                    });
+                }
+            });
+
+            socket.on('bye', function () {
+                console.log('received bye');
+            });
+
             Utils.Emit(socket, MessageStore.Foo, "handshooken");
 
             Utils.AddServerHandler(socket, MessageStore.Bar, guid => barReceived(socket, guid));
@@ -61,7 +111,6 @@ export namespace WebSocket {
             Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message));
             Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin);
 
-
             disconnect = () => {
                 socket.broadcast.emit("connection_terminated", Date.now());
                 socket.disconnect(true);
-- 
cgit v1.2.3-70-g09d2


From 38d0d467ee4c27709d482bfea7505e3f3729a455 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Sat, 8 Feb 2020 13:23:00 -0500
Subject: Ui Update and stream track stoppage added

---
 src/client/views/webcam/DashWebRTCVideo.scss | 30 +++++------
 src/client/views/webcam/DashWebRTCVideo.tsx  | 50 ++++++++++---------
 src/client/views/webcam/WebCamLogic.js       | 75 ++++++++++++++++------------
 src/server/Websocket/Websocket.ts            | 16 +++---
 4 files changed, 93 insertions(+), 78 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
index 262528d8e..052832db5 100644
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -27,14 +27,14 @@
         border: 1px solid #BBBBBBBB;
     }
 
-    #localVideo {
-        width: 50%;
-        height: 50%;
-        position: relative;
-        // top: 65%;
-        // z-index: 2;
-        // right: 5%;
-    }
+    // #localVideo {
+    //     width: 50%;
+    //     height: 50%;
+    //     position: relative;
+    //     // top: 65%;
+    //     // z-index: 2;
+    //     // right: 5%;
+    // }
 
     .side {
         width: 25%;
@@ -53,12 +53,12 @@
         align-self: center;
     }
 
-    #remoteVideo {
-        position: relative;
-        width: 50%;
-        height: 50%;
-        // top: 20%;
-        // align-self: center;
-    }
+    // #remoteVideo {
+    //     position: relative;
+    //     width: 50%;
+    //     height: 50%;
+    //     // top: 20%;
+    //     // align-self: center;
+    // }
 
 }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 191f5750d..f93d4a662 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -12,7 +12,7 @@ import { DocServer } from "../../DocServer";
 import { DocumentView } from "../nodes/DocumentView";
 import { Utils } from "../../../Utils";
 import { MessageStore } from "../../../server/Message";
-import { initialize } from "./WebCamLogic";
+import { initialize, hangup } from "./WebCamLogic";
 
 const mediaStreamConstraints = {
     video: true,
@@ -29,12 +29,12 @@ const offerOptions = {
 export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentViewProps & FieldViewProps> {
     @observable private localVideoEl: HTMLVideoElement | undefined;
     @observable private peerVideoEl: HTMLVideoElement | undefined;
-    // private roomText: HTMLInputElement | undefined;
+    private roomText: HTMLInputElement | undefined;
     // private roomOfCam: string = "";
     // private isChannelReady = false;
     // private isInitiator = false;
     // private isStarted = false;
-    // @observable remoteVideoAdded: boolean = false;
+    @observable remoteVideoAdded: boolean = false;
     // localStream: MediaStream | undefined;
     // private pc: any;
     // remoteStream: MediaStream | undefined;
@@ -56,17 +56,22 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     // };
 
     componentDidMount() {
-        // DocumentDecorations.Instance.addCloseCall(this.closeConnection);
-        setTimeout(() => initialize(), 10000);
+        DocumentDecorations.Instance.addCloseCall(this.closeConnection);
+        // setTimeout(() => initialize(), 10000);
         // let self = this;
         // window.onbeforeunload = function () {
         //     self.sendMessage('bye');
         // };
     }
 
-    // closeConnection: CloseCall = () => {
-    //     this.hangup();
-    // }
+    closeConnection: CloseCall = () => {
+        hangup();
+    }
+
+    @action
+    changeUILook = () => {
+        this.remoteVideoAdded = true;
+    }
 
     // componentWillUnmount() {
     // }
@@ -335,18 +340,17 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
 
 
 
-    // /**
-    //   * Function that submits the title entered by user on enter press.
-    //   */
-    // private onEnterKeyDown = (e: React.KeyboardEvent) => {
-    //     if (e.keyCode === 13) {
-    //         let submittedTitle = this.roomText!.value;
-    //         this.roomText!.value = "";
-    //         this.roomText!.blur();
-    //         this.roomOfCam = submittedTitle;
-    //         this.init(submittedTitle);
-    //     }
-    // }
+    /**
+      * Function that submits the title entered by user on enter press.
+      */
+    private onEnterKeyDown = (e: React.KeyboardEvent) => {
+        if (e.keyCode === 13) {
+            let submittedTitle = this.roomText!.value;
+            this.roomText!.value = "";
+            this.roomText!.blur();
+            initialize(submittedTitle, this.changeUILook);
+        }
+    }
 
 
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebRTCVideo, fieldKey); }
@@ -373,11 +377,11 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
         let content =
             <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 <div className="webcam-header">DashWebRTC</div>
-                {/* <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} /> */}
-                <video id="localVideo" autoPlay playsInline ref={(e) => {
+                <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
+                <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline ref={(e) => {
                     this.localVideoEl = e!;
                 }}></video>
-                <video id="remoteVideo" autoPlay playsInline ref={(e) => {
+                <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
                     this.peerVideoEl = e!;
                 }}></video>
 
diff --git a/src/client/views/webcam/WebCamLogic.js b/src/client/views/webcam/WebCamLogic.js
index d4798f72f..ffdcc4241 100644
--- a/src/client/views/webcam/WebCamLogic.js
+++ b/src/client/views/webcam/WebCamLogic.js
@@ -1,15 +1,17 @@
 'use strict';
 import io from "socket.io-client";
 
-export function initialize() {
-
-    var isChannelReady = false;
-    var isInitiator = false;
-    var isStarted = false;
-    var localStream;
-    var pc;
-    var remoteStream;
-    var turnReady;
+var socket;
+var isChannelReady = false;
+var isInitiator = false;
+var isStarted = false;
+var localStream;
+var pc;
+var remoteStream;
+var turnReady;
+var room;
+
+export function initialize(roomName, handlerUI) {
 
     var pcConfig = {
         'iceServers': [{
@@ -25,11 +27,11 @@ export function initialize() {
 
     /////////////////////////////////////////////
 
-    var room = 'foo';
+    room = roomName;
     // Could prompt for room name:
     // room = prompt('Enter room name:');
 
-    var socket = io.connect(`${window.location.protocol}//${window.location.hostname}:${4321}`);
+    socket = io.connect(`${window.location.protocol}//${window.location.hostname}:${4321}`);
 
     if (room !== '') {
         socket.emit('create or join', room);
@@ -62,10 +64,6 @@ export function initialize() {
 
     ////////////////////////////////////////////////
 
-    const sendMessage = (message) => {
-        console.log('Client sending message: ', message);
-        socket.emit('message', message);
-    };
 
     // This client receives a message
     socket.on('message', function (message) {
@@ -96,6 +94,7 @@ export function initialize() {
     var localVideo = document.querySelector('#localVideo');
     var remoteVideo = document.querySelector('#remoteVideo');
 
+
     console.log("Local Video: ", localVideo);
     console.log("Remote Video: ", remoteVideo);
 
@@ -241,28 +240,40 @@ export function initialize() {
         console.log('Remote stream added.');
         remoteStream = event.stream;
         remoteVideo.srcObject = remoteStream;
+        handlerUI();
+
     };
 
     const handleRemoteStreamRemoved = (event) => {
         console.log('Remote stream removed. Event: ', event);
     }
-
-    const hangup = () => {
-        console.log('Hanging up.');
-        stop();
-        sendMessage('bye');
-    }
-
-    const handleRemoteHangup = () => {
-        console.log('Session terminated.');
-        stop();
-        isInitiator = false;
+}
+
+export function hangup() {
+    console.log('Hanging up.');
+    stop();
+    sendMessage('bye');
+    if (localStream) {
+        localStream.getTracks().forEach(track => track.stop());
     }
-
-    const stop = () => {
-        isStarted = false;
-        pc.close();
-        pc = null;
+}
+
+function stop() {
+    isStarted = false;
+    pc.close();
+    pc = null;
+}
+
+function handleRemoteHangup() {
+    console.log('Session terminated.');
+    stop();
+    isInitiator = false;
+    if (localStream) {
+        localStream.getTracks().forEach(track => track.stop());
     }
+}
 
-}
\ No newline at end of file
+function sendMessage(message) {
+    console.log('Client sending message: ', message);
+    socket.emit('message', message);
+};
\ No newline at end of file
diff --git a/src/server/Websocket/Websocket.ts b/src/server/Websocket/Websocket.ts
index 96694bf72..30e7d6129 100644
--- a/src/server/Websocket/Websocket.ts
+++ b/src/server/Websocket/Websocket.ts
@@ -47,25 +47,25 @@ export namespace WebSocket {
             }
 
             socket.on('message', function (message) {
-                log('Client said: ', message);
+                console.log('Client said: ', message);
                 // for a real app, would be room-only (not broadcast)
                 socket.broadcast.emit('message', message);
             });
 
             socket.on('create or join', function (room) {
-                log('Received request to create or join room ' + room);
+                console.log('Received request to create or join room ' + room);
 
                 var clientsInRoom = socket.adapter.rooms[room];
                 var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
-                log('Room ' + room + ' now has ' + numClients + ' client(s)');
+                console.log('Room ' + room + ' now has ' + numClients + ' client(s)');
 
                 if (numClients === 0) {
                     socket.join(room);
-                    log('Client ID ' + socket.id + ' created room ' + room);
+                    console.log('Client ID ' + socket.id + ' created room ' + room);
                     socket.emit('created', room, socket.id);
 
                 } else if (numClients === 1) {
-                    log('Client ID ' + socket.id + ' joined room ' + room);
+                    console.log('Client ID ' + socket.id + ' joined room ' + room);
                     socket.in(room).emit('join', room);
                     socket.join(room);
                     socket.emit('joined', room, socket.id);
@@ -107,9 +107,9 @@ export namespace WebSocket {
             Utils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids));
             Utils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField);
             Utils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields);
-            Utils.AddServerHandler(socket, MessageStore.NotifyRoommates, message => HandleRoommateNotification(socket, message));
-            Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message));
-            Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin);
+            //Utils.AddServerHandler(socket, MessageStore.NotifyRoommates, message => HandleRoommateNotification(socket, message));
+            //Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message));
+            //Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin);
 
             disconnect = () => {
                 socket.broadcast.emit("connection_terminated", Date.now());
-- 
cgit v1.2.3-70-g09d2


From dac1b07c4b5ed42d50531e66ea3a1561f62ed11e Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Sun, 9 Feb 2020 14:33:51 -0500
Subject: CleanUp

---
 src/client/documents/Documents.ts            |   1 -
 src/client/views/webcam/DashWebCam.tsx       | 396 ---------------------------
 src/client/views/webcam/DashWebRTC.scss      |  23 --
 src/client/views/webcam/DashWebRTC.ts        | 314 ---------------------
 src/client/views/webcam/DashWebRTCVideo.scss |  18 --
 src/client/views/webcam/DashWebRTCVideo.tsx  | 312 +--------------------
 src/client/views/webcam/WebCamLogic.js       |   6 -
 src/server/Message.ts                        |   2 -
 src/server/Websocket/Websocket.ts            |  47 ----
 9 files changed, 1 insertion(+), 1118 deletions(-)
 delete mode 100644 src/client/views/webcam/DashWebCam.tsx
 delete mode 100644 src/client/views/webcam/DashWebRTC.scss
 delete mode 100644 src/client/views/webcam/DashWebRTC.ts

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index ba0f69846..7233fbea5 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -44,7 +44,6 @@ import { ComputedField, ScriptField } from "../../new_fields/ScriptField";
 import { ProxyField } from "../../new_fields/Proxy";
 import { DocumentType } from "./DocumentTypes";
 import { LinkFollowBox } from "../views/linking/LinkFollowBox";
-import { DashWebCam } from "../views/webcam/DashWebCam";
 import { PresElementBox } from "../views/presentationview/PresElementBox";
 import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo";
 import { QueryBox } from "../views/nodes/QueryBox";
diff --git a/src/client/views/webcam/DashWebCam.tsx b/src/client/views/webcam/DashWebCam.tsx
deleted file mode 100644
index a9669750f..000000000
--- a/src/client/views/webcam/DashWebCam.tsx
+++ /dev/null
@@ -1,396 +0,0 @@
-import React = require("react");
-import { observer } from "mobx-react";
-import { FieldViewProps, FieldView } from "../nodes/FieldView";
-import { observable, action } from "mobx";
-import { DocumentDecorations } from "../DocumentDecorations";
-import { InkingControl } from "../InkingControl";
-import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView";
-import "../../views/nodes/WebBox.scss";
-
-
-//https://github.com/mozmorris/react-webcam is the source code used for the bigger part of this implementation. It's only modified to fit our current system.
-
-
-function hasGetUserMedia() {
-    return !!(
-        (navigator.mediaDevices && navigator.mediaDevices.getUserMedia));
-}
-
-interface WebcamProps {
-    audio: boolean;
-    audioConstraints?: MediaStreamConstraints["audio"];
-    imageSmoothing: boolean;
-    minScreenshotHeight?: number;
-    minScreenshotWidth?: number;
-    onUserMedia: () => void;
-    onUserMediaError: (error: string) => void;
-    screenshotFormat: "image/webp" | "image/png" | "image/jpeg";
-    screenshotQuality: number;
-    videoConstraints?: MediaStreamConstraints["video"];
-}
-
-interface WebcamState {
-    hasUserMedia: boolean;
-    src?: string;
-}
-
-@observer
-export class DashWebCam extends React.Component<CollectionFreeFormDocumentViewProps & FieldViewProps & WebcamProps & React.HTMLAttributes<HTMLVideoElement> & {
-    layoutKey: string,
-}, WebcamState> {
-    static defaultProps = {
-        audio: true,
-        imageSmoothing: true,
-        onUserMedia: () => { },
-        onUserMediaError: () => { },
-        screenshotFormat: "image/webp",
-        screenshotQuality: 0.92
-    };
-
-    private static mountedInstances: DashWebCam[] = [];
-    private static userMediaRequested = false;
-    private canvas: HTMLCanvasElement | undefined;
-    private ctx: CanvasRenderingContext2D | null = null;
-    private stream: MediaStream | undefined;
-    private video: HTMLVideoElement | null | undefined;
-
-    // @observable private hasUserMedia: boolean | undefined;
-    // @observable private src: string | undefined;
-
-    constructor(props: any) {
-        super(props);
-        this.state = {
-            hasUserMedia: false
-        };
-    }
-
-    componentDidMount() {
-        if (!hasGetUserMedia()) return;
-
-        const { state } = this;
-
-        DashWebCam.mountedInstances.push(this);
-
-        if (!state.hasUserMedia && !DashWebCam.userMediaRequested) {
-            this.requestUserMedia();
-        }
-    }
-
-    componentDidUpdate(nextProps: WebcamProps) {
-        const { props } = this;
-        if (
-            JSON.stringify(nextProps.audioConstraints) !==
-            JSON.stringify(props.audioConstraints) ||
-            JSON.stringify(nextProps.videoConstraints) !==
-            JSON.stringify(props.videoConstraints)
-        ) {
-            this.requestUserMedia();
-        }
-    }
-
-    componentWillUnmount() {
-        const { state } = this;
-        const index = DashWebCam.mountedInstances.indexOf(this);
-        DashWebCam.mountedInstances.splice(index, 1);
-
-        DashWebCam.userMediaRequested = false;
-        if (DashWebCam.mountedInstances.length === 0 && state.hasUserMedia) {
-            if (this.stream!.getVideoTracks && this.stream!.getAudioTracks) {
-                this.stream!.getVideoTracks().map(track => track.stop());
-                this.stream!.getAudioTracks().map(track => track.stop());
-            } else {
-                ((this.stream as unknown) as MediaStreamTrack).stop();
-            }
-
-            if (state.src) {
-                window.URL.revokeObjectURL(state.src);
-            }
-        }
-    }
-
-    //These are for screenshot if wanted.
-
-    // getScreenshot() {
-    //     const { state, props } = this;
-
-    //     if (!state.hasUserMedia) return null;
-
-    //     const canvas = this.getCanvas();
-    //     return (
-    //         canvas &&
-    //         canvas.toDataURL(props.screenshotFormat, props.screenshotQuality)
-    //     );
-    // }
-
-    // getCanvas() {
-    //     const { state, props } = this;
-
-    //     if (!this.video) {
-    //         return null;
-    //     }
-
-    //     if (!state.hasUserMedia || !this.video.videoHeight) return null;
-
-    //     if (!this.ctx) {
-    //         const canvas = document.createElement("canvas");
-    //         const aspectRatio = this.video.videoWidth / this.video.videoHeight;
-
-    //         let canvasWidth = props.minScreenshotWidth || this.video.clientWidth;
-    //         let canvasHeight = canvasWidth / aspectRatio;
-
-    //         if (
-    //             props.minScreenshotHeight &&
-    //             canvasHeight < props.minScreenshotHeight
-    //         ) {
-    //             canvasHeight = props.minScreenshotHeight;
-    //             canvasWidth = canvasHeight * aspectRatio;
-    //         }
-
-    //         canvas.width = canvasWidth;
-    //         canvas.height = canvasHeight;
-
-    //         this.canvas = canvas;
-    //         this.ctx = canvas.getContext("2d");
-    //     }
-
-    //     const { ctx, canvas } = this;
-
-    //     if (ctx) {
-    //         ctx.imageSmoothingEnabled = props.imageSmoothing;
-    //         ctx.drawImage(this.video, 0, 0, canvas!.width, canvas!.height);
-    //     }
-
-    //     return canvas;
-    // }
-
-    requestUserMedia() {
-        const { props } = this;
-
-        navigator.getUserMedia =
-            navigator.mediaDevices.getUserMedia;
-
-        const sourceSelected = (audioConstraints: any, videoConstraints: any) => {
-            const constraints: MediaStreamConstraints = {
-                video: typeof videoConstraints !== "undefined" ? videoConstraints : true
-            };
-
-            if (props.audio) {
-                constraints.audio =
-                    typeof audioConstraints !== "undefined" ? audioConstraints : true;
-            }
-
-            navigator.mediaDevices
-                .getUserMedia(constraints)
-                .then(stream => {
-                    DashWebCam.mountedInstances.forEach(instance =>
-                        instance.handleUserMedia(null, stream)
-                    );
-                })
-                .catch(e => {
-                    DashWebCam.mountedInstances.forEach(instance =>
-                        instance.handleUserMedia(e)
-                    );
-                });
-        };
-
-        if ("mediaDevices" in navigator) {
-            sourceSelected(props.audioConstraints, props.videoConstraints);
-        } else {
-            const optionalSource = (id: any) => ({ optional: [{ sourceId: id }] });
-
-            const constraintToSourceId = (constraint: any) => {
-                const { deviceId } = constraint;
-
-                if (typeof deviceId === "string") {
-                    return deviceId;
-                }
-
-                if (Array.isArray(deviceId) && deviceId.length > 0) {
-                    return deviceId[0];
-                }
-
-                if (typeof deviceId === "object" && deviceId.ideal) {
-                    return deviceId.ideal;
-                }
-
-                return null;
-            };
-
-            // @ts-ignore: deprecated api
-            MediaStreamTrack.getSources(sources => {
-                let audioSource = null;
-                let videoSource = null;
-
-                sources.forEach((source: { kind: string; id: any; }) => {
-                    if (source.kind === "audio") {
-                        audioSource = source.id;
-                    } else if (source.kind === "video") {
-                        videoSource = source.id;
-                    }
-                });
-
-                const audioSourceId = constraintToSourceId(props.audioConstraints);
-                if (audioSourceId) {
-                    audioSource = audioSourceId;
-                }
-
-                const videoSourceId = constraintToSourceId(props.videoConstraints);
-                if (videoSourceId) {
-                    videoSource = videoSourceId;
-                }
-
-                sourceSelected(
-                    optionalSource(audioSource),
-                    optionalSource(videoSource)
-                );
-            });
-        }
-
-        DashWebCam.userMediaRequested = true;
-    }
-
-    handleUserMedia(err: string | null, stream?: MediaStream) {
-        const { props } = this;
-
-        if (err || !stream) {
-            this.setState({ hasUserMedia: false });
-            // action(() => this.hasUserMedia = false);
-            props.onUserMediaError(err!);
-
-            return;
-        }
-
-        this.stream = stream;
-
-        console.log("Stream done: ", stream);
-
-        try {
-            if (this.video) {
-                this.video.srcObject = stream;
-                console.log("Source  object: ", stream);
-
-            }
-            this.setState({ hasUserMedia: true });
-            // action(() => this.hasUserMedia = true);
-
-        } catch (error) {
-            this.setState({
-                hasUserMedia: true,
-                src: window.URL.createObjectURL(stream)
-            });
-            console.log("State  src set: ", this.state.src);
-
-            // action(() => this.hasUserMedia = true);
-            // action(() => this.src = window.URL.createObjectURL(stream));
-        }
-
-        props.onUserMedia();
-    }
-
-    _ignore = 0;
-    onPreWheel = (e: React.WheelEvent) => {
-        this._ignore = e.timeStamp;
-    }
-    onPrePointer = (e: React.PointerEvent) => {
-        this._ignore = e.timeStamp;
-    }
-    onPostPointer = (e: React.PointerEvent) => {
-        if (this._ignore !== e.timeStamp) {
-            e.stopPropagation();
-        }
-    }
-    onPostWheel = (e: React.WheelEvent) => {
-        if (this._ignore !== e.timeStamp) {
-            e.stopPropagation();
-        }
-    }
-
-
-
-
-    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebCam, fieldKey); }
-
-    render() {
-        const { state, props } = this;
-
-
-
-        const {
-            audio,
-            onUserMedia,
-            onUserMediaError,
-            screenshotFormat,
-            screenshotQuality,
-            minScreenshotWidth,
-            minScreenshotHeight,
-            audioConstraints,
-            videoConstraints,
-            imageSmoothing,
-            fieldKey,
-            fitToBox,
-            ContainingCollectionView,
-            Document,
-            DataDoc,
-            onClick,
-            isSelected,
-            select,
-            renderDepth,
-            addDocument,
-            addDocTab,
-            pinToPres,
-            removeDocument,
-            moveDocument,
-            ScreenToLocalTransform,
-            active,
-            whenActiveChanged,
-            focus,
-            PanelWidth,
-            PanelHeight,
-            setVideoBox,
-            ContentScaling,
-            ChromeHeight,
-            jitterRotation,
-            backgroundColor,
-            bringToFront,
-            zoomToScale,
-            getScale,
-            animateBetweenIcon,
-            layoutKey,
-            ...rest
-        } = props;
-
-        console.log("Source produced: ", state.src);
-
-
-
-        let content =
-            <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
-                <video
-                    autoPlay
-                    src={state.src}
-                    muted={!audio}
-                    playsInline
-                    ref={ref => {
-                        console.log("Source produced: ", state.src);
-                        console.log("HasUser Media produced: ", state.hasUserMedia);
-
-                        this.video = ref;
-                    }}
-                    {...rest}
-                />
-            </div>;
-
-
-        let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
-        let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
-
-        return (
-            <>
-                <div className={classname}  >
-                    {content}
-                </div>
-                {!frozen ? (null) : <div className="webBox-overlay" onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} />}
-            </>);
-
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTC.scss b/src/client/views/webcam/DashWebRTC.scss
deleted file mode 100644
index ddf4777a8..000000000
--- a/src/client/views/webcam/DashWebRTC.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-.webcam-cont {
-    button {
-        margin: 10px;
-        position: relative;
-        top: 20%;
-        left: -60%;
-    }
-
-    #localVideo {
-        margin: 10px;
-        position: relative;
-        width: 300px;
-        max-height: 300px;
-    }
-
-    #remoteVideo {
-        margin: 10px;
-        position: relative;
-        width: 300px;
-        max-height: 300px;
-
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts
deleted file mode 100644
index ef5ecf0fc..000000000
--- a/src/client/views/webcam/DashWebRTC.ts
+++ /dev/null
@@ -1,314 +0,0 @@
-// import { DocServer } from '../../DocServer';
-// import { Utils } from '../../../Utils';
-// import { MessageStore } from '../../../server/Message';
-
-
-
-// /**
-//  * This namespace will have the code required to have functionality code for the usage of webRTC.
-//  */
-// export class DashWebRTC {
-
-
-//     private isChannelReady = false;
-//     private isInitiator = false;
-//     private isStarted = false;
-//     localStream: MediaStream | undefined;
-//     private pc: any;
-//     remoteStream: MediaStream | undefined;
-//     private turnReady: boolean | undefined;
-//     localVideo: HTMLVideoElement | undefined;
-//     remoteVideo: HTMLVideoElement | undefined;
-//     curRoom: string = "";
-
-
-//     private pcConfig: any;
-//     private sdpConstraints: any;
-
-//     constructor() {
-//         this.pcConfig = {
-//             'iceServers': [{
-//                 'urls': 'stun:stun.l.google.com:19302'
-//             }]
-//         };
-
-//         // Set up audio and video regardless of what devices are present.
-//         this.sdpConstraints = {
-//             offerToReceiveAudio: true,
-//             offerToReceiveVideo: true
-//         };
-//     }
-
-
-
-//     init(room: string) {
-
-//         this.curRoom = room;
-//         let self = this;
-
-//         if (room !== '') {
-//             DocServer._socket.emit('create or join', room);
-//             console.log('Attempted to create or  join room', room);
-
-//         }
-
-//         DocServer._socket.on('created', function (room: string) {
-//             console.log('Created room ' + room);
-//             self.isInitiator = true;
-//         });
-
-//         DocServer._socket.on('full', function (room: string) {
-//             console.log('Room ' + room + ' is full');
-//         });
-
-//         DocServer._socket.on('join', function (room: string) {
-//             console.log('Another peer made a request to join room ' + room);
-//             console.log('This peer is the initiator of room ' + room + '!');
-//             self.isChannelReady = true;
-//         });
-
-
-//         DocServer._socket.on('joined', function (room: string) {
-//             console.log('joined: ' + room);
-//             self.isChannelReady = true;
-//         });
-
-
-//         DocServer._socket.on('log', function (array: any) {
-//             console.log.apply(console, array);
-//         });
-
-//         // This client receives a message
-//         DocServer._socket.on('message', function (message: any) {
-//             console.log('Client received message:', message);
-//             if (message.message === 'got user media') {
-//                 self.maybeStart();
-//             } else if (message.message.type === 'offer') {
-//                 if (!self.isInitiator && !self.isStarted) {
-//                     self.maybeStart();
-//                 }
-//                 self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-//                 self.doAnswer();
-//             } else if (message.message.type === 'answer' && self.isStarted) {
-//                 self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-//             } else if (message.message.type === 'candidate' && self.isStarted) {
-//                 let candidate = new RTCIceCandidate({
-//                     sdpMLineIndex: message.message.label,
-//                     candidate: message.message.candidate
-//                 });
-//                 self.pc.addIceCandidate(candidate);
-//             } else if (message === 'bye' && self.isStarted) {
-//                 self.handleRemoteHangup();
-//             }
-//         });
-
-//         navigator.mediaDevices.getUserMedia({
-//             audio: false,
-//             video: true
-//         })
-//             .then(this.gotStream)
-//             .catch(function (e) {
-//                 alert('getUserMedia() error: ' + e.name);
-//             });
-
-//         //Trying this one out!!!
-//         console.log('Getting user media with constraints', this.constraints);
-
-//         if (location.hostname !== 'localhost') {
-//             this.requestTurn(
-//                 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
-//             );
-//         }
-
-
-//     }
-
-
-//     sendMessage(message: any) {
-//         console.log('Client sending message: ', message);
-//         Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
-//         //DocServer._socket.emit('message', message);
-//     }
-
-
-
-
-
-//     setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) {
-//         this.localVideo = localVideo;
-//         this.remoteVideo = remoteVideo;
-//     }
-
-//     setLocalVideoObject(localVideoRef: HTMLVideoElement) {
-//         this.localVideo = localVideoRef;
-//     }
-
-//     setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) {
-//         this.remoteVideo = remoteVideoRef;
-//     }
-
-
-
-
-//     gotStream(stream: any) {
-//         console.log('Adding local stream.');
-//         this.localStream = stream;
-//         this.localVideo!.srcObject = stream;
-//         this.sendMessage('got user media');
-//         if (this.isInitiator) {
-//             this.maybeStart();
-//         }
-//     }
-
-//     constraints = {
-//         video: true,
-//         audio: true
-//     };
-
-
-
-
-
-//     maybeStart() {
-//         console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
-//         if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
-//             console.log('>>>>>> creating peer connection');
-//             this.createPeerConnection();
-//             this.pc.addStream(this.localStream);
-//             this.isStarted = true;
-//             console.log('isInitiator', this.isInitiator);
-//             if (this.isInitiator) {
-//                 this.doCall();
-//             }
-//         }
-//     }
-
-
-//     // //this will need to be changed to our version of hangUp
-//     // window.onbeforeunload = function () {
-//     //     sendMessage('bye');
-//     // };
-
-//     createPeerConnection() {
-//         try {
-//             this.pc = new RTCPeerConnection(undefined);
-//             this.pc.onicecandidate = this.handleIceCandidate;
-//             this.pc.onaddstream = this.handleRemoteStreamAdded;
-//             this.pc.onremovestream = this.handleRemoteStreamRemoved;
-//             console.log('Created RTCPeerConnnection');
-//         } catch (e) {
-//             console.log('Failed to create PeerConnection, exception: ' + e.message);
-//             alert('Cannot create RTCPeerConnection object.');
-//             return;
-//         }
-//     }
-
-//     handleIceCandidate(event: any) {
-//         console.log('icecandidate event: ', event);
-//         if (event.candidate) {
-//             this.sendMessage({
-//                 type: 'candidate',
-//                 label: event.candidate.sdpMLineIndex,
-//                 id: event.candidate.sdpMid,
-//                 candidate: event.candidate.candidate
-//             });
-//         } else {
-//             console.log('End of candidates.');
-//         }
-//     }
-
-//     handleCreateOfferError(event: any) {
-//         console.log('createOffer() error: ', event);
-//     }
-
-//     doCall() {
-//         console.log('Sending offer to peer');
-//         this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
-//     }
-
-//     doAnswer() {
-//         console.log('Sending answer to peer.');
-//         this.pc.createAnswer().then(
-//             this.setLocalAndSendMessage,
-//             this.onCreateSessionDescriptionError
-//         );
-//     }
-
-//     setLocalAndSendMessage(sessionDescription: any) {
-//         this.pc.setLocalDescription(sessionDescription);
-//         console.log('setLocalAndSendMessage sending message', sessionDescription);
-//         this.sendMessage(sessionDescription);
-//     }
-
-//     onCreateSessionDescriptionError(error: any) {
-//         console.log('Failed to create session description: ' + error.toString());
-//     }
-
-
-//     requestTurn(turnURL: any) {
-//         var turnExists = false;
-//         let self = this;
-//         for (var i in this.pcConfig.iceServers) {
-//             if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
-//                 turnExists = true;
-//                 this.turnReady = true;
-//                 break;
-//             }
-//         }
-//         if (!turnExists) {
-//             console.log('Getting TURN server from ', turnURL);
-//             // No TURN server. Get one from computeengineondemand.appspot.com:
-//             var xhr = new XMLHttpRequest();
-//             xhr.onreadystatechange = function () {
-//                 if (xhr.readyState === 4 && xhr.status === 200) {
-//                     var turnServer = JSON.parse(xhr.responseText);
-//                     console.log('Got TURN server: ', turnServer);
-//                     self.pcConfig.iceServers.push({
-//                         'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
-//                         //'credential': turnServer.password
-//                     });
-//                     self.turnReady = true;
-//                 }
-//             };
-//             xhr.open('GET', turnURL, true);
-//             xhr.send();
-//         }
-//     }
-
-//     handleRemoteStreamAdded(event: MediaStreamEvent) {
-//         console.log('Remote stream added.');
-//         this.remoteStream = event.stream!;
-//         this.remoteVideo!.srcObject = this.remoteStream;
-//     }
-
-//     handleRemoteStreamRemoved(event: MediaStreamEvent) {
-//         console.log('Remote stream removed. Event: ', event);
-//     }
-
-//     hangup() {
-//         console.log('Hanging up.');
-//         if (this.pc) {
-//             stop();
-//             this.sendMessage('bye');
-//         }
-
-//         if (this.localStream) {
-//             this.localStream.getTracks().forEach(track => track.stop());
-//         }
-
-//     }
-
-//     handleRemoteHangup() {
-//         console.log('Session terminated.');
-//         stop();
-//         this.isInitiator = false;
-//     }
-
-//     stop() {
-//         this.isStarted = false;
-//         this.pc.close();
-//         this.pc = null;
-//     }
-
-
-// }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
index 052832db5..2f35eeca2 100644
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -1,7 +1,6 @@
 @import "../globalCssVariables";
 
 .webcam-cont {
-    // position: absolute;
     background: whitesmoke;
     color: grey;
     border-radius: 15px;
@@ -27,15 +26,6 @@
         border: 1px solid #BBBBBBBB;
     }
 
-    // #localVideo {
-    //     width: 50%;
-    //     height: 50%;
-    //     position: relative;
-    //     // top: 65%;
-    //     // z-index: 2;
-    //     // right: 5%;
-    // }
-
     .side {
         width: 25%;
         height: 20%;
@@ -53,12 +43,4 @@
         align-self: center;
     }
 
-    // #remoteVideo {
-    //     position: relative;
-    //     width: 50%;
-    //     height: 50%;
-    //     // top: 20%;
-    //     // align-self: center;
-    // }
-
 }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index f93d4a662..0eefbbc91 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -8,60 +8,19 @@ import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
 import "./DashWebRTCVideo.scss";
 import adapter from 'webrtc-adapter';
-import { DocServer } from "../../DocServer";
-import { DocumentView } from "../nodes/DocumentView";
-import { Utils } from "../../../Utils";
-import { MessageStore } from "../../../server/Message";
 import { initialize, hangup } from "./WebCamLogic";
 
-const mediaStreamConstraints = {
-    video: true,
-};
-
-const offerOptions = {
-    offerToReceiveVideo: 1,
-};
-
 /**
  * This models the component that will be rendered, that can be used as a doc that will reflect the video cams.
  */
 @observer
 export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentViewProps & FieldViewProps> {
-    @observable private localVideoEl: HTMLVideoElement | undefined;
-    @observable private peerVideoEl: HTMLVideoElement | undefined;
+
     private roomText: HTMLInputElement | undefined;
-    // private roomOfCam: string = "";
-    // private isChannelReady = false;
-    // private isInitiator = false;
-    // private isStarted = false;
     @observable remoteVideoAdded: boolean = false;
-    // localStream: MediaStream | undefined;
-    // private pc: any;
-    // remoteStream: MediaStream | undefined;
-    // private turnReady: boolean | undefined;
-    // //localVideo: HTMLVideoElement | undefined;
-    // //remoteVideo: HTMLVideoElement | undefined;
-    // curRoom: string = "";
-
-    // private pcConfig = {
-    //     'iceServers': [{
-    //         'urls': 'stun:stun.l.google.com:19302'
-    //     }]
-    // };
-
-    // // Set up audio and video regardless of what devices are present.
-    // private sdpConstraints = {
-    //     offerToReceiveAudio: true,
-    //     offerToReceiveVideo: true
-    // };
 
     componentDidMount() {
         DocumentDecorations.Instance.addCloseCall(this.closeConnection);
-        // setTimeout(() => initialize(), 10000);
-        // let self = this;
-        // window.onbeforeunload = function () {
-        //     self.sendMessage('bye');
-        // };
     }
 
     closeConnection: CloseCall = () => {
@@ -73,273 +32,6 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
         this.remoteVideoAdded = true;
     }
 
-    // componentWillUnmount() {
-    // }
-
-
-    // init(room: string) {
-
-    //     this.curRoom = room;
-    //     let self = this;
-
-    //     if (room !== '') {
-    //         DocServer._socket.emit('create or join', room);
-    //         console.log('Attempted to create or  join room', room);
-
-    //     }
-
-    //     DocServer._socket.on('created', function (room: string) {
-    //         console.log('Created room ' + room);
-    //         self.isInitiator = true;
-    //     });
-
-    //     DocServer._socket.on('full', function (room: string) {
-    //         console.log('Room ' + room + ' is full');
-    //     });
-
-    //     DocServer._socket.on('join', function (room: string) {
-    //         console.log('Another peer made a request to join room ' + room);
-    //         console.log('This peer is the initiator of room ' + room + '!');
-    //         self.isChannelReady = true;
-    //     });
-
-
-    //     DocServer._socket.on('joined', function (room: string) {
-    //         console.log('joined: ' + room);
-    //         self.isChannelReady = true;
-    //     });
-
-
-    //     DocServer._socket.on('log', function (array: any) {
-    //         console.log.apply(console, array);
-    //     });
-
-    //     // This client receives a message
-    //     DocServer._socket.on('message', async function (message: any) {
-    //         console.log('Client received message:', message);
-    //         if (message.message === 'got user media') {
-    //             self.maybeStart();
-    //         } else if (message.message.type === 'offer') {
-    //             if (!self.isInitiator && !self.isStarted) {
-    //                 self.maybeStart();
-    //             }
-    //             await self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-    //             self.doAnswer();
-    //         } else if (message.message.type === 'answer' && self.isStarted) {
-    //             await self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
-    //         } else if (message.message.type === 'candidate' && self.isStarted) {
-    //             let candidate = new RTCIceCandidate({
-    //                 sdpMLineIndex: message.message.label,
-    //                 candidate: message.message.candidate
-    //             });
-    //             self.pc.addIceCandidate(candidate);
-    //         } else if (message.message === 'bye' && self.isStarted) {
-    //             self.handleRemoteHangup();
-    //         }
-    //     });
-
-    //     navigator.mediaDevices.getUserMedia({
-    //         audio: true,
-    //         video: true
-    //     })
-    //         .then(this.gotStream)
-    //         .catch(function (e) {
-    //             alert('getUserMedia() error: ' + e.name);
-    //         });
-
-    //     //Trying this one out!!!
-    //     console.log('Getting user media with constraints', this.constraints);
-
-    //     if (location.hostname !== 'localhost') {
-    //         this.requestTurn(
-    //             'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
-    //         );
-    //     }
-
-
-    // }
-
-
-    // private sendMessage = (message: any) => {
-    //     console.log('Client sending message: ', message);
-    //     Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom });
-    //     //DocServer._socket.emit('message', message);
-    // }
-
-
-
-    // private gotStream = (stream: any) => {
-    //     console.log('Adding local stream.');
-    //     this.localStream = stream;
-    //     this.localVideoEl!.srcObject = stream;
-    //     this.sendMessage('got user media');
-    //     if (this.isInitiator) {
-    //         this.maybeStart();
-    //     }
-    // }
-
-    // constraints = {
-    //     video: true,
-    //     audio: true
-    // };
-
-
-
-
-
-    // private maybeStart = () => {
-    //     console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady);
-    //     if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) {
-    //         console.log('>>>>>> creating peer connection');
-    //         this.createPeerConnection();
-    //         this.pc.addStream(this.localStream);
-    //         this.isStarted = true;
-    //         console.log('isInitiator', this.isInitiator);
-    //         if (this.isInitiator) {
-    //             this.doCall();
-    //         }
-    //     }
-    // }
-
-
-    // // //this will need to be changed to our version of hangUp
-    // // window.onbeforeunload = function () {
-    // //     sendMessage('bye');
-    // // };
-
-    // private createPeerConnection = () => {
-    //     try {
-    //         this.pc = new RTCPeerConnection(undefined);
-    //         this.pc.onicecandidate = this.handleIceCandidate;
-    //         this.pc.onaddstream = this.handleRemoteStreamAdded;
-    //         this.pc.onremovestream = this.handleRemoteStreamRemoved;
-    //         console.log('Created RTCPeerConnnection');
-    //     } catch (e) {
-    //         console.log('Failed to create PeerConnection, exception: ' + e.message);
-    //         alert('Cannot create RTCPeerConnection object.');
-    //         return;
-    //     }
-    // }
-
-    // private handleIceCandidate = (event: any) => {
-    //     console.log('icecandidate event: ', event);
-    //     if (event.candidate) {
-    //         this.sendMessage({
-    //             type: 'candidate',
-    //             label: event.candidate.sdpMLineIndex,
-    //             id: event.candidate.sdpMid,
-    //             candidate: event.candidate.candidate
-    //         });
-    //     } else {
-    //         console.log('End of candidates.');
-    //     }
-    // }
-
-    // private handleCreateOfferError = (event: any) => {
-    //     console.log('createOffer() error: ', event);
-    // }
-
-    // private doCall = () => {
-    //     console.log('Sending offer to peer');
-    //     this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError);
-    // }
-
-    // private doAnswer = () => {
-    //     console.log('Sending answer to peer.');
-    //     this.pc.createAnswer().then(
-    //         this.setLocalAndSendMessage,
-    //         this.onCreateSessionDescriptionError
-    //     );
-    // }
-
-    // private setLocalAndSendMessage = (sessionDescription: any) => {
-    //     this.pc.setLocalDescription(sessionDescription);
-    //     console.log('setLocalAndSendMessage sending message', sessionDescription);
-    //     this.sendMessage(sessionDescription);
-    // }
-
-    // private onCreateSessionDescriptionError = (error: any) => {
-    //     console.log('Failed to create session description: ' + error.toString());
-    // }
-
-
-    // private requestTurn = (turnURL: any) => {
-    //     var turnExists = false;
-    //     let self = this;
-    //     for (var i in this.pcConfig.iceServers) {
-    //         if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
-    //             turnExists = true;
-    //             this.turnReady = true;
-    //             break;
-    //         }
-    //     }
-    //     if (!turnExists) {
-    //         console.log('Getting TURN server from ', turnURL);
-    //         // No TURN server. Get one from computeengineondemand.appspot.com:
-    //         var xhr = new XMLHttpRequest();
-    //         xhr.onreadystatechange = function () {
-    //             if (xhr.readyState === 4 && xhr.status === 200) {
-    //                 var turnServer = JSON.parse(xhr.responseText);
-    //                 console.log('Got TURN server: ', turnServer);
-    //                 self.pcConfig.iceServers.push({
-    //                     'urls': 'turn:' + turnServer.username + '@' + turnServer.turn,
-    //                     //'credential': turnServer.password
-    //                 });
-    //                 self.turnReady = true;
-    //             }
-    //         };
-    //         xhr.open('GET', turnURL, true);
-    //         xhr.send();
-    //     }
-    // }
-    // @action
-    // private handleRemoteStreamAdded = (event: MediaStreamEvent) => {
-    //     console.log('Remote stream added.');
-    //     this.remoteStream = event.stream!;
-    //     this.peerVideoEl!.srcObject = this.remoteStream;
-    //     this.remoteVideoAdded = true;
-    // }
-
-    // private handleRemoteStreamRemoved = (event: MediaStreamEvent) => {
-    //     console.log('Remote stream removed. Event: ', event);
-    // }
-
-    // private hangup = () => {
-    //     console.log('Hanging up.');
-    //     if (this.pc) {
-    //         stop();
-    //         this.sendMessage('bye');
-    //     }
-
-    //     if (this.localStream) {
-    //         this.localStream.getTracks().forEach(track => track.stop());
-    //     }
-
-    // }
-
-    // private handleRemoteHangup = () => {
-    //     console.log('Session terminated.');
-    //     this.stop();
-    //     this.isInitiator = false;
-
-    //     if (this.localStream) {
-    //         this.localStream.getTracks().forEach(track => track.stop());
-    //     }
-
-
-    // }
-
-    // private stop = () => {
-    //     this.isStarted = false;
-    //     this.pc.close();
-    //     this.pc = null;
-    // }
-
-
-
-
-
-
     /**
       * Function that submits the title entered by user on enter press.
       */
@@ -379,10 +71,8 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
                 <div className="webcam-header">DashWebRTC</div>
                 <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
                 <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline ref={(e) => {
-                    this.localVideoEl = e!;
                 }}></video>
                 <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
-                    this.peerVideoEl = e!;
                 }}></video>
 
             </div >;
diff --git a/src/client/views/webcam/WebCamLogic.js b/src/client/views/webcam/WebCamLogic.js
index ec8b2e8bf..a7af9c2c4 100644
--- a/src/client/views/webcam/WebCamLogic.js
+++ b/src/client/views/webcam/WebCamLogic.js
@@ -28,8 +28,6 @@ export function initialize(roomName, handlerUI) {
     /////////////////////////////////////////////
 
     room = roomName;
-    // Could prompt for room name:
-    // room = prompt('Enter room name:');
 
     socket = io.connect(`${window.location.protocol}//${window.location.hostname}:${4321}`);
 
@@ -94,10 +92,6 @@ export function initialize(roomName, handlerUI) {
     var localVideo = document.querySelector('#localVideo');
     var remoteVideo = document.querySelector('#remoteVideo');
 
-
-    console.log("Local Video: ", localVideo);
-    console.log("Remote Video: ", remoteVideo);
-
     const gotStream = (stream) => {
         console.log('Adding local stream.');
         localStream = stream;
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 6ce5cd96a..79b6fa1e0 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -64,8 +64,6 @@ export namespace MessageStore {
     export const YoutubeApiQuery = new Message<YoutubeQueryInput>("Youtube Api Query");
     export const DeleteField = new Message<string>("Delete field");
     export const DeleteFields = new Message<string[]>("Delete fields");
-    export const NotifyRoommates = new Message<RoomMessage>("message");
-    export const HangUpCall = new Message<string>("bye");
 
 
 }
diff --git a/src/server/Websocket/Websocket.ts b/src/server/Websocket/Websocket.ts
index b4cd2dbe2..ba7ca8f35 100644
--- a/src/server/Websocket/Websocket.ts
+++ b/src/server/Websocket/Websocket.ts
@@ -19,7 +19,6 @@ export namespace WebSocket {
     const clients: { [key: string]: Client } = {};
     export const socketMap = new Map<SocketIO.Socket, string>();
     export let disconnect: Function;
-    let endpoint: io.Server;
 
 
     export async function start(isRelease: boolean) {
@@ -107,9 +106,6 @@ export namespace WebSocket {
             Utils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids));
             Utils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField);
             Utils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields);
-            //Utils.AddServerHandler(socket, MessageStore.NotifyRoommates, message => HandleRoommateNotification(socket, message));
-            //Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message));
-            //Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin);
 
             disconnect = () => {
                 socket.broadcast.emit("connection_terminated", Date.now());
@@ -122,49 +118,6 @@ export namespace WebSocket {
         logPort("websocket", socketPort);
     }
 
-
-    function HandleRoommateNotification(socket: Socket, message: RoomMessage) {
-        //socket.broadcast.emit('message', message);
-        console.log("The room that sent this: ", message.room, " and message is : ", message.message);
-        endpoint.sockets.in(message.room).emit('message', message);
-
-    }
-
-    function HandleCreateOrJoin(socket: io.Socket, room: string) {
-        console.log("Received request to create or join room " + room);
-
-
-        let clientsInRoom = endpoint.sockets.adapter.rooms[room];
-        let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
-        console.log('Room ' + room + ' now has ' + numClients + ' client(s)');
-
-
-        if (numClients === 0) {
-            socket.join(room);
-            console.log('Client ID ' + socket.id + ' created room ' + room);
-            socket.emit('created', room, socket.id);
-
-        } else if (numClients === 1) {
-            console.log('Client ID ' + socket.id + ' joined room ' + room);
-            endpoint.sockets.in(room).emit('join', room);
-            socket.join(room);
-            socket.emit('joined', room, socket.id);
-            endpoint.sockets.in(room).emit('ready');
-
-        } else {
-            socket.emit('full', room);
-        }
-
-
-
-
-
-    }
-
-    function HandleHangUp(socket: io.Socket, message: string) {
-        console.log("Receive bye from someone");
-    }
-
     function HandleYoutubeQuery([query, callback]: [YoutubeQueryInput, (result?: any[]) => void]) {
         const { ProjectCredentials } = GoogleCredentialsLoader;
         switch (query.type) {
-- 
cgit v1.2.3-70-g09d2


From 98990f419c2316b17bd397f27f606396dfede684 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Tue, 11 Feb 2020 19:15:09 -0500
Subject: muted local video audio

---
 src/client/views/webcam/DashWebRTCVideo.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index 0eefbbc91..cbf75f708 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -70,7 +70,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
             <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 <div className="webcam-header">DashWebRTC</div>
                 <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
-                <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline ref={(e) => {
+                <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline muted ref={(e) => {
                 }}></video>
                 <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
                 }}></video>
-- 
cgit v1.2.3-70-g09d2


From 4059607ef104a2d3d59e505a3ec0ae2820df3160 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com>
Date: Tue, 11 Feb 2020 23:57:40 -0500
Subject: HangUp and refresh and ui update

---
 src/client/views/webcam/DashWebRTCVideo.scss | 49 +++++++++++++++++++++---
 src/client/views/webcam/DashWebRTCVideo.tsx  | 57 +++++++++++++---------------
 src/client/views/webcam/WebCamLogic.js       | 14 ++++++-
 3 files changed, 82 insertions(+), 38 deletions(-)

(limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')

diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
index 2f35eeca2..41307a808 100644
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -4,7 +4,7 @@
     background: whitesmoke;
     color: grey;
     border-radius: 15px;
-    box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
+    box-shadow: #9c9396 0.2vw 0.2vw 0.4vw;
     border: solid #BBBBBBBB 5px;
     pointer-events: all;
     display: flex;
@@ -18,29 +18,66 @@
         letter-spacing: 2px;
         font-size: 16px;
         width: 100%;
+        margin-top: 20px;
+    }
+
+    .videoContainer {
+        position: relative;
+        width: calc(100% - 20px);
+        height: 100%;
+        /* border: 10px solid red; */
+        margin-left: 10px;
+    }
+
+    .buttonContainer {
+        display: flex;
+        width: calc(100% - 20px);
+        height: 50px;
+        justify-content: center;
+        text-align: center;
+        /* border: 1px solid black; */
+        margin-left: 10px;
+        margin-top: 0;
+        margin-bottom: 15px;
     }
 
     #roomName {
         outline: none;
         border-radius: inherit;
         border: 1px solid #BBBBBBBB;
+        margin: 10px;
+        padding: 10px;
     }
 
     .side {
         width: 25%;
         height: 20%;
         position: absolute;
-        top: 65%;
+        /* top: 65%; */
         z-index: 2;
-        right: 5%;
+        right: 0px;
+        bottom: 18px;
     }
 
     .main {
         position: absolute;
-        width: 95%;
-        height: 75%;
-        top: 20%;
+        width: 100%;
+        height: 100%;
+        /* top: 20%; */
+        align-self: center;
+    }
+
+    .videoButtons {
+        border-radius: 50%;
+        height: 30px;
+        width: 30px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        justify-self: center;
         align-self: center;
+        margin: 5px;
+        border: 1px solid black;
     }
 
 }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index cbf75f708..9c339e986 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -8,7 +8,14 @@ import { InkingControl } from "../InkingControl";
 import "../../views/nodes/WebBox.scss";
 import "./DashWebRTCVideo.scss";
 import adapter from 'webrtc-adapter';
-import { initialize, hangup } from "./WebCamLogic";
+import { initialize, hangup, refreshVideos } from "./WebCamLogic";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
+import { faSync, faPhoneSlash } from "@fortawesome/free-solid-svg-icons";
+
+library.add(faSync);
+library.add(faPhoneSlash);
+
 
 /**
  * This models the component that will be rendered, that can be used as a doc that will reflect the video cams.
@@ -19,14 +26,6 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
     private roomText: HTMLInputElement | undefined;
     @observable remoteVideoAdded: boolean = false;
 
-    componentDidMount() {
-        DocumentDecorations.Instance.addCloseCall(this.closeConnection);
-    }
-
-    closeConnection: CloseCall = () => {
-        hangup();
-    }
-
     @action
     changeUILook = () => {
         this.remoteVideoAdded = true;
@@ -47,34 +46,30 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
 
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebRTCVideo, fieldKey); }
 
-    _ignore = 0;
-    onPreWheel = (e: React.WheelEvent) => {
-        this._ignore = e.timeStamp;
-    }
-    onPrePointer = (e: React.PointerEvent) => {
-        this._ignore = e.timeStamp;
-    }
-    onPostPointer = (e: React.PointerEvent) => {
-        if (this._ignore !== e.timeStamp) {
-            e.stopPropagation();
-        }
+    @action
+    onClickRefresh = () => {
+        refreshVideos();
     }
-    onPostWheel = (e: React.WheelEvent) => {
-        if (this._ignore !== e.timeStamp) {
-            e.stopPropagation();
-        }
+
+    onClickHangUp = () => {
+        hangup();
     }
 
     render() {
         let content =
-            <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+            <div className="webcam-cont" style={{ width: "100%", height: "100%" }}>
                 <div className="webcam-header">DashWebRTC</div>
                 <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
-                <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline muted ref={(e) => {
-                }}></video>
-                <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
-                }}></video>
-
+                <div className="videoContainer">
+                    <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline muted ref={(e) => {
+                    }}></video>
+                    <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
+                    }}></video>
+                </div>
+                <div className="buttonContainer">
+                    <div className="videoButtons" style={{ background: "red" }} onClick={this.onClickHangUp}><FontAwesomeIcon icon={faPhoneSlash} color="white" /></div>
+                    <div className="videoButtons" style={{ background: "green" }} onClick={this.onClickRefresh}><FontAwesomeIcon icon={faSync} color="white" /></div>
+                </div>
             </div >;
 
         let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
@@ -86,7 +81,7 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV
                 <div className={classname}  >
                     {content}
                 </div>
-                {!frozen ? (null) : <div className="webBox-overlay" onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} />}
+                {!frozen ? (null) : <div className="webBox-overlay" />}
             </>);
     }
 
diff --git a/src/client/views/webcam/WebCamLogic.js b/src/client/views/webcam/WebCamLogic.js
index bd1f5c847..d5330af9a 100644
--- a/src/client/views/webcam/WebCamLogic.js
+++ b/src/client/views/webcam/WebCamLogic.js
@@ -277,4 +277,16 @@ function handleRemoteHangup() {
 function sendMessage(message) {
     console.log('Client sending message: ', message);
     socket.emit('message', message, room);
-};
\ No newline at end of file
+};
+
+export function refreshVideos() {
+    var localVideo = document.querySelector('#localVideo');
+    var remoteVideo = document.querySelector('#remoteVideo');
+    if (localVideo) {
+        localVideo.srcObject = localStream;
+    }
+    if (remoteVideo) {
+        remoteVideo.srcObject = remoteStream;
+    }
+
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

