Browse code

Changed majority of files.

DoubleBastionAdmin authored on 30/11/2024 06:56:40
Showing 1 changed files
... ...
@@ -1,6 +1,6 @@
1 1
 <?php
2 2
 /**
3
- *  Copyright (C) 2021  Double Bastion LLC
3
+ *  Copyright (C) 2022, 2024  Double Bastion LLC
4 4
  *
5 5
  *  This file is part of Roundpin, which is licensed under the
6 6
  *  GNU Affero General Public License Version 3.0. The license terms
... ...
@@ -20,64 +20,101 @@
20 20
 
21 21
 session_start();
22 22
 
23
+header('Set-Cookie: PHPSESSID= ' . session_id() . '; SameSite=strict; Secure=true; HttpOnly=true;');
24
+
23 25
 if ($_SESSION['loggedtoroundpin'] == true) {
24 26
 
27
+    $vidConferenceExt = $_GET['extensionvidconf'];
28
+    $vidConferenceTag = $_GET['tagvideoconf'];
25 29
 ?>
26 30
 
27
-<script type="text/javascript">
28
-    let validateSToken = "<?php print_r($_SESSION['validate_s_access']); ?>";
29
-    let userName = "<?php print_r($_SESSION['loginname']); ?>";
30
-</script>
31
-
32 31
 <!DOCTYPE html>
33 32
 
34 33
 <html>
35 34
 <head>
36 35
 	<meta charset="utf-8" />
37 36
 	<title>Roundpin Video Conference</title>
38
-	<link rel="stylesheet" type="text/css" href="css/conference-phone.min.css">
37
+	<link rel="stylesheet" type="text/css" href="css/conference-phone.css">
39 38
         <link rel="stylesheet" type="text/css" href="../fonts/font-awesome-4.7.0/css/font-awesome.min.css"/>
40
-
41 39
         <link rel="stylesheet" type="text/css" href="../css/jeegoo-1.0.0.min.css"/>
42 40
 
43 41
         <link rel="shortcut icon" type="image/svg" href="../images/favicon.svg" />
42
+
44 43
 	<script type="text/javascript" src="js/sdp-interop-sl-1.4.0.min.js"></script>
45
-        <script type="text/javascript" src="js/jssip-3.7.0.min.js"></script>
44
+        <script type="text/javascript" src="js/jssip-3.9.1.min.js"></script>
46 45
 	<script type="text/javascript" src="js/utils.min.js"></script>
47 46
         <script type="text/javascript" src="../js/jquery-3.3.1.min.js"></script>
48
-
49
-	<script type="text/javascript" src="js/conference-phone.min.js"></script>
50
-
47
+        <script type="text/javascript" src="js/conference-phone.js"></script>
48
+        <script type="text/javascript" src="../js/moment-with-locales-2.24.0.min.js"></script>
51 49
         <script type="text/javascript" src="../js/jquery.jeegoopopup.1.0.0.min.js"></script>
50
+        <script type="text/javascript" src="../js/fix-webm-duration.js"></script>
51
+        <script type="text/javascript" src="../js/crypto-js-4.1.1.min.js"></script>
52
+        <script type="text/javascript" src="../js/jsencrypt.min.js"></script>
52 53
 
53 54
 <script type="text/javascript">
54 55
 
55
-let phone;
56
-let numPressed = null;
56
+// JsSIP.debug.enable('*');
57 57
 
58
-window.onload = function() {
58
+let validateSToken = "<?php print_r($_SESSION['validate_s_access']); ?>";
59
+let userName = "<?php print_r($_SESSION['loginname']); ?>";
60
+let videoConfExtension = "<?php print_r($vidConferenceExt); ?>";
61
+let videoConfTag = "<?php print_r($vidConferenceTag); ?>";
59 62
 
60
-        var mvcount = 0;
61
-        var sipPassDec = '';
63
+// Check if window is visible to hide notifications if needed
64
+document.addEventListener('visibilitychange', function() { if (document.hidden) { vcDocIsVisible = false; } else { vcDocIsVisible = true; }});
62 65
 
63
-	document.getElementById("connect").value = "Connect";
64
-	document.getElementById("connect").disabled = false;
65
-	document.getElementById("call").value = "Call";
66
-	document.getElementById("call").disabled = true;
67
-        document.getElementById("call").style.display = 'none';
68
-        document.getElementById("fullscreen").style.display = 'none';
66
+window.onload = function() {
69 67
 
70
-	function findMediaView(parent, stream) {
71
-		let nodes = parent.childNodes;
68
+        localStorage.setItem('vConfOpenCheck', 'open');
69
+        let remoteCheck = 0;
70
+        let sipPassDec = '';
71
+
72
+        // Generate a new text chat key pair for the current video conference participant
73
+	let cryptousr = new JSEncrypt({default_key_size: 1024});
74
+	cryptousr.getKey();
75
+	let crVConfUserPubKey = cryptousr.getPublicKey();
76
+	crVConfUserPrivKey = cryptousr.getPrivateKey();
77
+
78
+	$.ajax({
79
+	     type: "POST",
80
+	     url: "../src/save-text-chat-pub-key.php",
81
+	     dataType: "JSON",
82
+	     data: {
83
+                     currentextension: crUserExt,
84
+	             currentchatpubkey: crVConfUserPubKey,
85
+		     s_ajax_call: validateSToken
86
+	     },
87
+	     success: function() {
88
+	     },
89
+	     error: function() {
90
+		        alert("An error occurred while attempting to save the new text chat public key!");
91
+	     }
92
+	});
72 93
 
73
-		for (let i = 0; i < nodes.length; ++i) {
74
-			if (nodes[i].id == stream.id) {
75
-				return nodes[i];
76
-			}
77
-		}
78
-		return null;
79
-	}
94
+        // Generate a RSA key pair for the video conference extension if it hasn't been already generated by a participant who entered the conference earlier
95
+	let crypto = new JSEncrypt({default_key_size: 1024});
96
+	crypto.getKey();
97
+	let crVConfChatPubKey = crypto.getPublicKey();
98
+	let crVConfChatPrivKey = crypto.getPrivateKey();
99
+
100
+	$.ajax({
101
+	     type: "POST",
102
+	     url: "../src/save-text-chat-vconf-keys.php",
103
+	     dataType: "JSON",
104
+	     data: {
105
+		     currentvconfext: videoConfExtension,
106
+	             currentvconfpubkey: crVConfChatPubKey,
107
+                     currentvconfprivkey: crVConfChatPrivKey,
108
+		     s_ajax_call: validateSToken
109
+	     },
110
+	     success: function() {
111
+	     },
112
+	     error: function() {
113
+		        alert("An error occurred while trying to save the new text chat public key!");
114
+	     }
115
+	});
80 116
 
117
+        // Show dialpad
81 118
         function dtmfMenuShow() {
82 119
 
83 120
                 $.jeegoopopup.close();
... ...
@@ -90,27 +127,27 @@ window.onload = function() {
90 127
 		}
91 128
 
92 129
 	        var html = "<div id=\"sendPinDialPad\">";
93
-	        html += "<div><input type=\"text\" id=\"dialText\" class=\"dialTextInput\"></div>";
130
+	        html += "<div><input type=\"text\" id=\"dialText\"></div>";
94 131
 	        html += "<table cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">";
95
-	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('1');new Audio('../sounds/dtmf.mp3').play();\"><div>1</div><span>&nbsp;</span></button></td>";
96
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('2');new Audio('../sounds/dtmf.mp3').play();\"><div>2</div><span>ABC</span></button></td>";
97
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('3');new Audio('../sounds/dtmf.mp3').play();\"><div>3</div><span>DEF</span></button></td></tr>";
98
-	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('4');new Audio('../sounds/dtmf.mp3').play();\"><div>4</div><span>GHI</span></button></td>";
99
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('5');new Audio('../sounds/dtmf.mp3').play();\"><div>5</div><span>JKL</span></button></td>";
100
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('6');new Audio('../sounds/dtmf.mp3').play();\"><div>6</div><span>MNO</span></button></td></tr>";
101
-	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('7');new Audio('../sounds/dtmf.mp3').play();\"><div>7</div><span>PQRS</span></button></td>";
102
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('8');new Audio('../sounds/dtmf.mp3').play();\"><div>8</div><span>TUV</span></button></td>";
103
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('9');new Audio('../sounds/dtmf.mp3').play();\"><div>9</div><span>WXYZ</span></button></td></tr>";
104
-	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('*');new Audio('../sounds/dtmf.mp3').play();\">*</button></td>";
105
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('0');new Audio('../sounds/dtmf.mp3').play();\">0</button></td>";
106
-	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('#');new Audio('../sounds/dtmf.mp3').play();\">#</button></td></tr>";
132
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('1');new Audio('../sounds/dtmf.ogg').play();\"><div>1</div><span>&nbsp;</span></button></td>";
133
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('2');new Audio('../sounds/dtmf.ogg').play();\"><div>2</div><span>ABC</span></button></td>";
134
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('3');new Audio('../sounds/dtmf.ogg').play();\"><div>3</div><span>DEF</span></button></td></tr>";
135
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('4');new Audio('../sounds/dtmf.ogg').play();\"><div>4</div><span>GHI</span></button></td>";
136
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('5');new Audio('../sounds/dtmf.ogg').play();\"><div>5</div><span>JKL</span></button></td>";
137
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('6');new Audio('../sounds/dtmf.ogg').play();\"><div>6</div><span>MNO</span></button></td></tr>";
138
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('7');new Audio('../sounds/dtmf.ogg').play();\"><div>7</div><span>PQRS</span></button></td>";
139
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('8');new Audio('../sounds/dtmf.ogg').play();\"><div>8</div><span>TUV</span></button></td>";
140
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('9');new Audio('../sounds/dtmf.ogg').play();\"><div>9</div><span>WXYZ</span></button></td></tr>";
141
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('*');new Audio('../sounds/dtmf.ogg').play();\">*</button></td>";
142
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('0');new Audio('../sounds/dtmf.ogg').play();\">0</button></td>";
143
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('#');new Audio('../sounds/dtmf.ogg').play();\">#</button></td></tr>";
107 144
 	        html += "</table>";
108 145
 	        html += "</div>";
109 146
 
110 147
 	        $.jeegoopopup.open({
111 148
 			html: html,
112
-			width: "auto",
113
-			height: "auto",
149
+			width: 160,
150
+			height: 265,
114 151
 			left: leftPos,
115 152
 			top: topPos,
116 153
 			scrolling: 'no',
... ...
@@ -122,15 +159,39 @@ window.onload = function() {
122 159
 			fadeIn: 0
123 160
 	        });
124 161
 
125
-	        $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); });
126
-	        $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } });
162
+	        $(window).resize(function() {
163
+                        $.jeegoopopup.width(160).height(265);
164
+                        $.jeegoopopup.center();
165
+                });
166
+
167
+		$("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); });
168
+		$(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } });
127 169
         }
128 170
 
129
-	function createMediaControls(video) {
171
+
172
+        // Create media control buttons
173
+	function createMediaControls(video, strid) {
130 174
 
131 175
 		let controls = document.createElement("div");
132 176
 		controls.className = "media-controls";
133 177
 
178
+                // Hangup
179
+                if (video.srcObject.local == true) {
180
+		        let hangupBtn = document.createElement("button");
181
+                        hangupBtn.className = "mediaControlBtn";
182
+                        hangupBtn.id = "hangupConf";
183
+		        hangupBtn.innerHTML = '<i class="fa fa-power-off" aria-hidden="true" title="Hangup"></i>';
184
+                        hangupBtn.onclick = function() {
185
+                                               if (confirm("Do you really want to leave the conference ?")) {
186
+                                                   try { phone.disconnect(); } catch(e) { return; }
187
+                                                   window.close();
188
+                                               }
189
+                        }
190
+
191
+		        controls.appendChild(hangupBtn);
192
+                }
193
+
194
+                // Open keypad
134 195
                 if (video.srcObject.local == true) {
135 196
 		        let sendPin = document.createElement("button");
136 197
                         sendPin.className = "mediaControlBtn";
... ...
@@ -141,69 +202,577 @@ window.onload = function() {
141 202
 		        controls.appendChild(sendPin);
142 203
                 }
143 204
 
205
+                // Public conference messaging
206
+                if (video.srcObject.local == true) {
207
+
208
+		        let textChat = document.createElement("button");
209
+                        textChat.className = "mediaControlBtn";
210
+                        textChat.id = "textChatBtn";
211
+		        textChat.innerHTML = '<i class="fa fa-commenting-o" aria-hidden="true" title="Send Public Message..."></i>';
212
+                        textChat.onclick = function() {
213
+
214
+                                if (messageWindowState != 'closed') { alert("The public messaging window is already open!"); return; }
215
+
216
+				var chathtml = "<div id=\"publicTextMessages\">";
217
+                                chathtml += "<div id=\"windowCtrls\"><img id=\"closeImg\" src=\"../images/3_close.svg\" title=\"Close\"><img id=\"maximizeImg\" src=\"../images/2_maximize.svg\" title=\"Maximize\"><img id=\"restoreImg\" src=\"../images/4_restore.svg\" title=\"Restore\"><img id=\"minimizeImg\" src=\"../images/1_minimize.svg\" title=\"Minimize\"><img id=\"publicMessageImg\" src=\"../images/PublicMessage.svg\" title=\"Public Message\"></div>";
218
+                                chathtml += "<div id=\"dragPubMessageWindow\" style=\"display:block;position:absolute;width:100%;height:10px;top:4px;text-align:center;z-index:20;\"><i id=\"dragPublicMWindow\" class=\"fa fa-ellipsis-h\" aria-hidden=\"true\" title=\"Drag Button\" style=\"display:block;position:relative;margin: 0px auto;color:#d0d0d0;font-size:17px;cursor:grab;\"></i></div>";
219
+				chathtml += "<div id='pubMTopBar' style='display:block;margin: 8px auto;text-align:center;padding-bottom: 6px;'><img src='../images/small-logo.svg' style='display:block;position:relative;margin: 7px auto 0px auto;padding-left:80px;user-select: none;pointer-events: none;' draggable='false'><span style='display:inline-block;margin: -6px 0px 0px 0px;font-weight:600;color:#224573;user-select: none;'>Public Text Messaging - Room: <span style='color:#379b77'>"+ videoConfTag +"</span> ("+ videoConfExtension +")</span></div>";
220
+				chathtml += "<div id=\"receiveTextMessage\"><div id='downloadVConfHst' title='Download Text Conversation'><i class='fa fa-download'></i></div></div>";
221
+                                chathtml += "<div id=\"emojiMenu\" style=\"display:none\"></div>";
222
+                                chathtml += "<div id=\"sendTMessage\"><table cellspacing=\"0\" cellpadding=\"0\" id=\"sendMessageTbl\"><tr><td style=\"height: 100%;width: 100%;\"><textarea id=\"sendTextMessage\" class=\"chatMessage\" placeholder=\"Type the message here, then click the paper plane button or press Ctrl + Enter to send it.\"></textarea></td>";
223
+                                chathtml += "<td style=\"display:block;width:36px;margin:0px;\"><button id=\"sendTextChatBtn\" class=\"roundButtonsSpec\" title=\"Send Message\"><i class=\"fa fa-paper-plane-o\" aria-hidden=\"true\"></i></button>";
224
+                                chathtml += "<button id=\"selectEmoticon\" class=\"roundButtonsSpec\" title=\"Select Emoticon\"><i class=\"fa fa-smile-o\"></i></button>";
225
+                                chathtml += "<button id=\"sendFileVC\" class=\"roundButtonsSpec\" title=\"Send File\"><i class=\"fa fa-file-text-o\"></i></button></td></tr></table></div>";
226
+				chathtml += "</div>";
227
+
228
+                                $("#media-views").append(chathtml);
229
+                                $("#publicTextMessages").css("display", "block");
230
+
231
+                                $("#restoreImg").hide();
232
+				$("#sendTextMessage").focus();
233
+                                messageWindowState = 'restored';
234
+
235
+                                // Bring window forward when clicking on it
236
+                                $("#publicTextMessages").click(function (e) {
237
+                                   if (!$(e.target).hasClass('recMessageBtn')) {
238
+                                       $("#publicTextMessages").css("z-index", 21);
239
+                                   }
240
+                                });
241
+
242
+                                // Make the window draggable
243
+				function makePubWndDraggable(e){
244
+
245
+				       window.pmdragging = {};
246
+				       pmdragging.pageX0 = e.pageX;
247
+				       pmdragging.pageY0 = e.pageY;
248
+                                       pmdragging.elem = $("#publicTextMessages");
249
+                                       pmdragging.offset0 = $("#publicTextMessages").offset();
250
+
251
+				       function handle_dragging(e){
252
+					   var left = pmdragging.offset0.left + (e.pageX - pmdragging.pageX0);
253
+					   var top = pmdragging.offset0.top + (e.pageY - pmdragging.pageY0);
254
+					   $(pmdragging.elem).offset({top: top, left: left});
255
+				       }
256
+
257
+				       function handle_mouseup(e){
258
+					   $('body').off('mousemove', handle_dragging).off('mouseup', handle_mouseup);
259
+				       }
260
+
261
+				       $('body').on('mouseup', handle_mouseup).on('mousemove', handle_dragging);
262
+				}
263
+
264
+                                $("#dragPubMessageWindow").mousedown(makePubWndDraggable);
265
+
266
+
267
+                                // Open private message window when clicking on username in received message
268
+                                $("#receiveTextMessage").on("click", ".recMessageBtn", function() {
269
+
270
+                                   var messageDestPre = $(this).text();
271
+                                   var messageDest = messageDestPre.slice(0, -2);
272
+                                   var crntExtenfirst = messageDest.split("(");
273
+                                   var crntExtensec = crntExtenfirst[1].split(")");
274
+                                   var crntTgtExten = crntExtensec[0];
275
+                                   if (messageWindowStatePM[crntTgtExten] == 'minimized' || messageWindowStatePM[crntTgtExten] == 'restored') {
276
+                                       alert("The private messaging window for this conference participant is already open!");
277
+                                   } else {
278
+                                       phone.openPrivateMessageWindow(messageDest, crntTgtExten);
279
+                                   }
280
+                                });
281
+
282
+                                // Select emoticon
283
+                                $("#selectEmoticon").click(function() {
284
+
285
+				    var messageContainer = $("#emojiMenu");
286
+				    var textarea = $("#sendTextMessage");
287
+
288
+				    if (messageContainer.is(":visible")) { messageContainer.hide(); } else { messageContainer.show(); }
289
+
290
+				    var menuBar = $("<div>");
291
+				    menuBar.prop("class", "emojiButton");
292
+				    var emojis = ["😀","😁","😂","😃","😄","😅","😆","😊","😦","😉","😊","😋","😌","😍","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😛","😜","😝","😞","😟","😠","😡","😢","😣","😤","😥","😦","😧","😨","😩","😪","😫","😬","😭","😮","😯","😰","😱","😲","😳","😴","😵","😶","😷","🙁","🙂","🙃","🙄","🤐","🤑","🤒","🤓","🤔","🤕","🤠","🤡","🤢","🤣","🤤","🤥","🤧","🤨","🤩","🤪","🤫","🤬","🤭","🤯","🤗","🧐"];
293
+				    $.each(emojis, function(i,e){
294
+					       var emoji = $("<button>");
295
+					       emoji.html(e);
296
+					       emoji.on('click', function() {
297
+						    var i = textarea.prop('selectionStart');
298
+						    var v = textarea.val();
299
+						    textarea.val(v.substring(0, i) + " " + $(this).html() + v.substring(i, v.length) + " ");
300
+
301
+						    messageContainer.hide();
302
+						    textarea.focus();
303
+					       });
304
+					       menuBar.append(emoji);
305
+				    });
306
+
307
+				    $("#sendTextMessage,#receiveTextMessage").on('click', function() {
308
+				       messageContainer.hide();
309
+				    });
310
+
311
+				    messageContainer.empty();
312
+				    messageContainer.append(menuBar);
313
+                                });
314
+
315
+				// Show the 'Download Text Conversation' button
316
+				$("#receiveTextMessage").mouseenter(function() {
317
+				   $("#downloadVConfHst").css("display", "block");
318
+				});
319
+				$("#receiveTextMessage").mouseleave(function() {
320
+				   $("#downloadVConfHst").css("display", "none");
321
+				});
322
+
323
+				// Download chat history
324
+				$("#downloadVConfHst").click(function() { phone.DownloadChatHistoryVC(videoConfExtension, videoConfTag); });
325
+
326
+                                // Send message to video conference participants
327
+                                function SendPubChatMessage() {
328
+
329
+                                        let textToSendRaw = $("#sendTextMessage").val().trim();
330
+                                        let textToSend = phone.ReformatVCMessage(textToSendRaw);
331
+                                        let targetUser = '';
332
+
333
+				        // When a file is sent
334
+				        if (sendFileCheckVC == 1) {
335
+
336
+                                             $("#receiveTextMessage").append("<span id='sendFileLoaderVC'></span>");
337
+                                             sendFileChatErrVC = '';
338
+
339
+                                             $("#sendFileFormChatVC").on('submit', function(ev) {
340
+
341
+				                   ev.preventDefault();
342
+
343
+						   $.ajax({
344
+							type: 'POST',
345
+							url: '../src/text-chat-vconf-upload-file.php',
346
+							data: new FormData(this),
347
+							dataType: "JSON",
348
+							contentType: false,
349
+							cache: false,
350
+							processData:false,
351
+							success: function(respdata) { 
352
+
353
+                                                                    var mserrorcheck = false;
354
+
355
+								    if (respdata.error != '') {
356
+
357
+                                                                        sendFileChatErrVC = respdata.error;
358
+									$("#sendFileFormChatVC").remove();
359
+									$("#sendFileLoaderVC").remove();
360
+                                                                        sendFileCheckVC = 0;
361
+									alert("Error: " + respdata.error);
362
+
363
+								    } else {
364
+
365
+                                                                        // Send the text message
366
+								        phone.sendConfMessage(textToSendRaw, { From: profileName + " (" + crUserExt + "): ", To: targetUser, handlers: {
367
+									   onSuccessResponse(response) {
368
+									       console.log("Message Sent: " + response);
369
+									   },
370
+									   onErrorResponse(response) {
371
+                                                                               mserrorcheck = true;
372
+									       console.log("Message ERROR: " + response);
373
+                                                                               alert("The message couldn't be sent. Message ERROR: " + response);
374
+									   },
375
+									   onTransportError() {
376
+									       console.log("Could not send message");
377
+									   },
378
+									   onRequestTimeout() {
379
+									       console.log("Timeout sending message");
380
+									   },
381
+									   onDialogError() {
382
+									      console.log("Dialog Error sending message");
383
+									   },
384
+								        }});
385
+
386
+
387
+                                                                        if (mserrorcheck == false) {
388
+
389
+							                    $("#sendTextMessage").val("");
390
+							                    let currentTime = new Date().toLocaleTimeString();
391
+
392
+                                                                            // Append the sent message
393
+							                    if (textToSend != '') {
394
+							                        $("#receiveTextMessage").append("<div class='textMessageSent textMsgVConf'><span class='sentMessageBtn'>"+ profileName +" ("+ crUserExt +"):</span><div class='srMsgVConfcont'>"+ textToSend +"</div><div class='messageDate'>"+ currentTime +"<i class='fa fa-check sentMsTick' title='No errors on message sending'></i></div></div>"); 
395
+							                    }
396
+
397
+                                                                            // Append the 'Download file' section
398
+							                    let currentflTime = new Date().toLocaleTimeString();
399
+							                    $("#receiveTextMessage").append("<div class='textMessageSent textMsgVConf'><span class='sentMessageBtn'>"+ profileName +" ("+ crUserExt +"):</span><div class='srMsgVConfcont'>Download file: <a href='../src/download-sent-chat-file.php?s_ajax_call="+ validateSToken +"&destSipUser="+ videoConfExtension +"&sentFlNm="+ upFileNameVC +"' target='_blank'>"+ upFileNameVC +"</a></div><div class='messageDate'>"+ currentflTime +"</div></div>");
400
+
401
+//									    $("#sendFileFormChatVC").remove();
402
+//					                                    $("#sendFileLoaderVC").remove();
403
+                                                                        }
404
+
405
+								        $("#sendFileFormChatVC").remove();
406
+                                                                        $("#sendFileLoaderVC").remove();
407
+                                                                    }
408
+
409
+							},
410
+							error: function(respdata) {
411
+								    $("#sendFileFormChatVC").remove();
412
+								    $("#sendFileLoaderVC").remove();
413
+								    alert("An error occurred while sending the file!");
414
+							}     
415
+						   });
416
+
417
+                                             });
418
+
419
+                                             $("#sendFileFormChatVC").submit();
420
+
421
+				        } else {
422
+
423
+                                               var mserrorcheckwf = false;
424
+
425
+                                               // Send the text message
426
+					       phone.sendConfMessage(textToSendRaw, { From: profileName + " (" + crUserExt + "): ", To: targetUser, handlers: {
427
+					          onSuccessResponse(response) {
428
+						      console.log("Message Sent: " + response);
429
+					          },
430
+					          onErrorResponse(response) {
431
+                                                      mserrorcheckwf = true;
432
+						      console.log("Message ERROR: " + response);
433
+                                                      alert("The message couldn't be sent. Message ERROR: " + response);
434
+					          },
435
+					          onTransportError() {
436
+						      console.log("Could not send message");
437
+					          },
438
+					          onRequestTimeout() {
439
+						      console.log("Timeout sending message");
440
+					          },
441
+					          onDialogError() {
442
+						      console.log("Dialog Error sending message");
443
+					          },
444
+					       }});
445
+
446
+                                               if (mserrorcheckwf == false) {
447
+
448
+                                                   $("#sendTextMessage").val("");
449
+                                                   let currentTime = new Date().toLocaleTimeString();
450
+
451
+                                                   // Append the sent message
452
+                                                   if (textToSend != '') {
453
+                                                       $("#receiveTextMessage").append("<div class='textMessageSent textMsgVConf'><span class='sentMessageBtn'>"+ profileName +" ("+ crUserExt +"):</span><div class='srMsgVConfcont'>"+ textToSend +"</div><div class='messageDate'>"+ currentTime +"<i class='fa fa-check sentMsTick' title='No errors on message sending'></i></div></div>"); 
454
+                                                   }
455
+
456
+//                                                   $("#sendFileLoaderVC").remove();
457
+                                               }
458
+
459
+                                        }
460
+                       
461
+                                        $("#receiveTextMessage").scrollTop($("#receiveTextMessage")[0].scrollHeight);
462
+
463
+                                }
464
+
465
+                                // Send the message when clicking on the 'Send Message' button
466
+				$("#sendTextChatBtn").click(function() { SendPubChatMessage(); });
467
+
468
+                                // Send the message when pressing Ctrl + Enter
469
+                                $("#sendTextMessage").keydown(function() {
470
+				    var keycode = (event.keyCode ? event.keyCode : event.which);
471
+				    if (keycode == '13') {
472
+				        if (event.ctrlKey) {
473
+					    SendPubChatMessage();
474
+					    return false;
475
+				        }
476
+				    }
477
+                                });
478
+
479
+
480
+                                // Select the file to send
481
+                                $("#sendFileVC").click(function() {
482
+
483
+				      $('#selectedFileVC').val('');
484
+				      $("#upFileVC").empty();
485
+
486
+				      var uploadfilevc = '<form id="sendFileFormChatVC" enctype="multipart/form-data">';
487
+				      uploadfilevc += '<input type="hidden" name="MAX_FILE_SIZE" value="786432000" />';
488
+				      uploadfilevc += '<input type="hidden" name="vcextension" value="'+ videoConfExtension +'" />';
489
+				      uploadfilevc += '<input type="hidden" name="s_ajax_call" value="'+ validateSToken +'" />';
490
+				      uploadfilevc += '<label for="selectedFileVC" class="customBrowseButtonVC">Select File</label>';
491
+				      uploadfilevc += '<span id="upFileVC"></span>';
492
+				      uploadfilevc += '<input type="file" id="selectedFileVC" name="uploadedFileVC" />';
493
+				      uploadfilevc += '<input type="submit" id="submitFileChatVC" value="Send File" style="visibility:hidden;"/>';
494
+				      uploadfilevc += '</form>';
495
+
496
+
497
+				      if ($("#sendFileFormChatVC").is(":visible")) {
498
+					  $("#sendFileFormChatVC").remove();
499
+					  sendFileCheckVC = 0;
500
+				      } else {
501
+                                          sendFileCheckVC = 1;
502
+					  $("#sendTextMessage").before(uploadfilevc);
503
+					  $("#sendFileFormChatVC").css("display", "block");
504
+
505
+					  $("#selectedFileVC").bind("change", function() {
506
+					     upFileNameVC = $(this).val().split('\\').pop();
507
+					     if (/^[a-zA-Z0-9\-\_\.]+$/.test(upFileNameVC)) {
508
+                                                 $("#upFileVC").css("display", "inline-block");
509
+						 $("#upFileVC").html(upFileNameVC);
510
+//                                                 sendFileCheckVC = 1;
511
+					     } else { 
512
+						   $("#sendFileFormChatVC").remove();
513
+						   sendFileCheckVC = 0;
514
+						   alert("The name of the uploaded file is not valid!");
515
+					     }
516
+					  });
517
+				      }
518
+
519
+                                });
520
+
521
+
522
+                                // Position the window
523
+			        let maxHeight = parseInt(0.88 * $(window).height());
524
+			        let maxWidth = parseInt(maxHeight * 1.24);
525
+                                let wTop = parseInt( ($(window).height() / 2) - 290 );
526
+                                let wLeft = parseInt( ($(window).width() / 2) - 280 );
527
+                                $("#publicMessageImg").hide();
528
+
529
+
530
+			        if (maxWidth < 620 || maxHeight < 500) { 
531
+			            $("#publicTextMessages").css({ "width": maxWidth, "height": maxHeight, "top": wTop, "left": wLeft });
532
+			            $("#maximizeImg").hide();
533
+                                    $("#restoreImg").hide();
534
+			        } else { 
535
+			            $("#publicTextMessages").css({ "width": 620, "height": 500, "top": wTop, "left": wLeft });
536
+                                    $("#minimizeImg").show();
537
+			            $("#maximizeImg").show();
538
+                                    $("#restoreImg").hide();
539
+			        }
540
+
541
+                                // Handle window position when resizing browser window
542
+			        $(window).resize(function() {
543
+
544
+			          let maxHeight = parseInt(0.88 * $(window).height());
545
+                                  let maxWidth = parseInt(maxHeight * 1.24);
546
+                                  let wTop = parseInt( ($(window).height() / 2) - 290 );
547
+                                  let wLeft = parseInt( ($(window).width() / 2) - 280 );
548
+                                  $("#receiveTextMessage").show();
549
+                                  $("#sendTMessage").show();
550
+                                  $("#pubMTopBar").show();
551
+                                  $("#publicMessageImg").hide();
552
+
553
+
554
+			          if (maxWidth < 620 || maxHeight < 500) { 
555
+				      $("#publicTextMessages").css({ "width": maxWidth, "height": maxHeight, "top": wTop, "left": wLeft });
556
+				      $("#maximizeImg").hide();
557
+                                      $("#restoreImg").hide();
558
+			          } else { 
559
+				      $("#publicTextMessages").css({ "width": 620, "height": 500, "top": wTop, "left": wLeft });
560
+       				      $("#minimizeImg").show();
561
+				      $("#maximizeImg").show();
562
+                                      $("#restoreImg").hide();
563
+			          }
564
+
565
+			        });
566
+
567
+                                // Handle clicking on window control buttons
568
+			        $("#maximizeImg").click(function() { messageWindowState = 'maximized'; $("#publicTextMessages").css({ "width": maxWidth, "height": maxHeight, "top": wTop - 40, "left": wLeft - 40 }); $("#maximizeImg,#publicMessageImg").hide(); $("#minimizeImg,#pubMTopBar,#restoreImg,#receiveTextMessage,#sendTMessage").show(); $("#receiveTextMessage").css("height", "64%"); $("#recPubMessage").remove(); });
569
+			        $("#minimizeImg").click(function() { messageWindowState = 'minimized'; $("#publicTextMessages").css({ "display": "block", "position": "fixed", "width": 215, "height": 34, "inset": "auto auto 1px 3px" }); $("#minimizeImg,#pubMTopBar,#receiveTextMessage,#sendTMessage").hide(); $("#maximizeImg,#restoreImg,#publicMessageImg").show(); $("#windowCtrls").css("margin", "10px 10px 0px 0px"); $("#dragPubMessageWindow").css("top", "-1px"); });
570
+                                $("#restoreImg").click(function() { messageWindowState = 'restored'; $("#publicTextMessages").css({ "width": 620, "height": 500, "top": wTop, "left": wLeft }); $("#restoreImg,#publicMessageImg").hide(); $("#maximizeImg,#pubMTopBar,#minimizeImg,#receiveTextMessage,#sendTMessage").show(); $("#receiveTextMessage").css("height", "54%"); $("#dragPubMessageWindow").css("top", "4px"); $("#recPubMessage").remove(); });
571
+			        $("#closeImg").click(function() { messageWindowState = 'closed'; $("#publicTextMessages").remove();  $("#recPubMessage").remove(); });
572
+
573
+			        $(window).on('keydown', function(event) { if (event.key == "Escape") { messageWindowState = 'closed'; $("#publicTextMessages").remove();  $("#recPubMessage").remove(); } });
574
+
575
+                        }
576
+
577
+		        controls.appendChild(textChat);
578
+                }
579
+
580
+                // Private conference messaging
581
+                if (video.srcObject.local == false) {
582
+
583
+		        let pmtextChat = document.createElement("button");
584
+                        pmtextChat.className = "mediaControlBtn";
585
+                        pmtextChat.id = "textChatBtnPM";
586
+		        pmtextChat.innerHTML = '<i class="fa fa-commenting-o" aria-hidden="true" title="Send private message to this user"></i>';
587
+                        pmtextChat.onclick = function() {
588
+				   let currentMView = document.getElementById("new-media-view"+strid);
589
+				   let crMViewName = currentMView.getAttribute("name");
590
+				   let targetCnfExt = crMViewName.slice(4);
591
+
592
+                                   let currentVidView = document.getElementById("video-view"+strid);
593
+                                   let destName = currentVidView.getAttribute("name") + " ("+ targetCnfExt +")";
594
+
595
+                                   if (messageWindowStatePM[targetCnfExt] == 'minimized' || messageWindowStatePM[targetCnfExt] == 'restored') {
596
+                                       alert("The private message window for this conference participant is already open!");
597
+                                   } else {
598
+                                       phone.openPrivateMessageWindow(destName, targetCnfExt);
599
+                                   }
600
+                        }
601
+		        controls.appendChild(pmtextChat);
602
+                }
603
+
604
+                // Record conference
605
+                if (video.srcObject.local == true) {
606
+		        let recordConf = document.createElement("button");
607
+                        recordConf.className = "mediaControlBtn";
608
+                        recordConf.id = "recordConfBtnStart";
609
+		        recordConf.innerHTML = '<i class="fa fa-dot-circle-o" aria-hidden="true" title="Record Conference..."></i>';
610
+                        recordConf.onclick = function() { phone.recordVideoConference(); }
611
+
612
+		        controls.appendChild(recordConf);
613
+                }
614
+
615
+                // Expel participant
616
+                if (video.srcObject.local == false && (userRole == 'superadmin' || userRole == 'admin')) {
617
+                        let kickUser = document.createElement("button");
618
+                        kickUser.className = "mediaControlBtn";
619
+                        kickUser.innerHTML = '<i class="fa fa-sign-out" aria-hidden="true" title="Eject Participant"></i>';
620
+			kickUser.onclick = function() {
621
+
622
+				if (confirm("Do you really want to eject this participant from this conference ?")) {
623
+
624
+				    var currentMView = document.getElementById("new-media-view"+strid);
625
+				    var crMViewName = currentMView.getAttribute("name");
626
+				    var targetExt = crMViewName.slice(4);
627
+				    var cfExtenAndChannel = videoConfExtension + " " + localStorage.getItem(targetExt);
628
+
629
+                                    var currentVidView = document.getElementById("video-view"+strid);
630
+                                    var bannedPrflName = currentVidView.getAttribute("name");
631
+
632
+				    var banhtml = "<div id='enterBanTime'>";
633
+				    banhtml += "<div id='banTimeDesc'><img id='vConfPrefLogo' src='../images/small-logo.svg' />";
634
+				    banhtml += "<div id='banTimeTitle'><i class='fa fa-clock-o' style='display:inline-block;margin-right:7px;'></i>Ban Time</div>";
635
+				    banhtml += "<div id='banTimeText'>Enter the number of days (including the current day) for which you want to ban the user <b>'"+ bannedPrflName +"'</b> (Extension "+ targetExt +") from the conference '"+ videoConfTag + "' (Extension "+ videoConfExtension +"). If you want to eject the user without banning him, just eter 0</div></div>";
636
+				    banhtml += "<div><input type='text' id='banTimeBox' placeholder='Enter a number between 0 and 73000'></div>";
637
+				    banhtml += "<div><input type='submit' id='banTimeSubmit' value='Ban for the mentioned number of days'></div>";
638
+				    banhtml += "</div>";
639
+
640
+                                    $("#media-views").append(banhtml);
641
+
642
+                                    var maxWidthban = parseInt($(window).width());
643
+                                    var maxHeightban = parseInt($(window).height());
644
+                                    var leftBanwnd = parseInt((maxWidthban / 2) - 150);
645
+                                    var topBanwnd = parseInt((maxHeightban / 2) - 150);
646
+
647
+                                    $("#enterBanTime").css({ "display" : "block", "top" : topBanwnd, "left" : leftBanwnd });
648
+
649
+
650
+                                    $("#banTimeSubmit").click(function() {
651
+
652
+                                        var banTimeVal = $("#banTimeBox").val().trim();
653
+
654
+                                        if (banTimeVal != '') {
655
+
656
+                                            if (/^[0-9]+$/.test(banTimeVal) && parseInt(banTimeVal) >= 0 && parseInt(banTimeVal) <= 73000) {
657
+
658
+						$.ajax({
659
+						    type: "POST",
660
+						    url: "../src/save-conference-ban-time.php",
661
+						    dataType: "JSON",
662
+						    data: {
663
+							    username: userName,
664
+                                                            bannedprofilename: bannedPrflName,
665
+                                                            bannedsipusername: targetExt,
666
+                                                            confextension: videoConfExtension,
667
+                                                            conflabel: videoConfTag,
668
+                                                            banneddays: banTimeVal,
669
+							    s_ajax_call: validateSToken
670
+						    },
671
+						    success: function (response) {
672
+
673
+		                                             if (response.result == 'success') {
674
+                                                                 $("#enterBanTime").remove();
675
+								 phone.callToKick('conferencekout', cfExtenAndChannel);
676
+
677
+		                                             } else { alert("Error while trying to save the ban time to the database!"); }
678
+						    },
679
+						    error: function(response) {
680
+							       alert("Error while attempting to save the ban time to the database!");
681
+						    }
682
+						});
683
+
684
+                                            } else { alert("Please enter a natural number between 0 and 73000 !"); }
685
+
686
+                                        } else { alert("Please enter the ban time !"); }
687
+                                    });
688
+				}
689
+                        };
690
+                        controls.appendChild(kickUser);
691
+                }
692
+
693
+                // Mute/Unmute audio
144 694
 		let audioTracks = video.srcObject.getAudioTracks();
145 695
 		if (audioTracks.length > 0) {
146 696
                         let muteAudio = document.createElement("button");
147 697
                         muteAudio.className = "mediaControlBtn";
148
-                        muteAudio.innerHTML = '<i class="fa fa-microphone-slash" aria-hidden="true" title="Mute Audio"></i>';
149
-			muteAudio.setAttribute("state", "Unmute");
698
+                        muteAudio.innerHTML = '<i class="fa fa-microphone" aria-hidden="true" title="Mute Audio"></i>';
699
+			muteAudio.setAttribute("state", "unmute");
150 700
 			muteAudio.onclick = function() {
151 701
 				let state = this.getAttribute("state");
152
-                                if (state == "Mute") {
153
-                                    this.setAttribute("state", "Unmute");
154
-                                    this.innerHTML = '<i class="fa fa-microphone-slash" aria-hidden="true" title="Mute Audio"></i>';
155
-                                } else if (state == "Unmute") {
156
-                                    this.setAttribute("state", "Mute");
157
-                                    this.innerHTML = '<i class="fa fa-microphone" aria-hidden="true" title="Unmute Audio"></i>';
702
+                                if (state == "mute") {
703
+                                    this.setAttribute("state", "unmute");
704
+                                    this.innerHTML = '<i class="fa fa-microphone" aria-hidden="true" title="Mute Audio"></i>';
705
+                                } else if (state == "unmute") {
706
+                                    this.setAttribute("state", "mute");
707
+                                    this.innerHTML = '<i class="fa fa-microphone redmic" aria-hidden="true" title="Unmute Audio"></i>';
158 708
                                 }
159
-				mute(video.srcObject, {audio: this.getAttribute("state") == "Mute"});
709
+				mute(video.srcObject, {audio: this.getAttribute("state") == "mute"});
160 710
 			};
161 711
 			controls.appendChild(muteAudio);
162 712
 		}
163 713
 
714
+
164 715
 		let videoTracks = video.srcObject.getVideoTracks();
165 716
 		if (videoTracks.length > 0) {
717
+
718
+                        // Mute/Unmute video
166 719
                         let muteVideo = document.createElement("button");
167 720
                         muteVideo.className = "mediaControlBtn";
168
-                        muteVideo.innerHTML = '<i class="fa fa-ban" aria-hidden="true" title="Mute Video"></i>';
169
-			muteVideo.setAttribute("state", "Unmute");
721
+                        muteVideo.innerHTML = '<i class="fa fa-camera" aria-hidden="true" title="Mute Video"></i>';
722
+			muteVideo.setAttribute("state", "unmute");
170 723
 			muteVideo.onclick = function() {
724
+
171 725
 				let state = this.getAttribute("state");
172
-                                if (state == "Mute") {
173
-                                    this.setAttribute("state", "Unmute");
174
-                                    this.innerHTML = '<i class="fa fa-ban" aria-hidden="true" title="Mute Video"></i>';
175
-                                } else if (state == "Unmute") {
176
-                                    this.setAttribute("state", "Mute");
177
-                                    this.innerHTML = '<i class="fa fa-video-camera" aria-hidden="true" title="Unmute Video"></i>';
726
+                                if (state == "mute") {
727
+                                    this.setAttribute("state", "unmute");
728
+                                    this.innerHTML = '<i class="fa fa-camera" aria-hidden="true" title="Mute Video"></i>';
729
+                                } else if (state == "unmute") {
730
+                                    this.setAttribute("state", "mute");
731
+                                    this.innerHTML = '<i class="fa fa-camera redcam" aria-hidden="true" title="Unmute Video"></i>';
178 732
                                 }
179 733
 
180
-				mute(video.srcObject, {video: this.getAttribute("state") == "Mute"});
734
+				mute(video.srcObject, {video: this.getAttribute("state") == "mute"});
735
+
181 736
 			};
182 737
 			controls.appendChild(muteVideo);
183 738
 
184 739
                         if (video.srcObject.local == true) {
740
+
741
+                                // Share screen
185 742
                                 let ScreenShare = document.createElement("button");
186 743
                                 ScreenShare.className = "mediaControlBtn";
187
-                                ScreenShare.innerHTML = '<i class="fa fa-desktop" aria-hidden="true" title="Share Screen"></i>';
744
+                                ScreenShare.innerHTML = '<i class="fa fa-desktop" aria-hidden="true" title="Share Screen..."></i>';
188 745
 				ScreenShare.onclick = function() {
189 746
 					phone.ShareScreen();
190 747
 				};
191 748
 
192 749
 				controls.appendChild(ScreenShare);
193 750
 
751
+                                // Reshare camera
194 752
                                 let VideoShare = document.createElement("button");
195 753
                                 VideoShare.className = "mediaControlBtn";
196
-                                VideoShare.innerHTML = '<i class="fa fa-video-camera" aria-hidden="true" title="Share Camera"></i>';
754
+                                VideoShare.innerHTML = '<i class="fa fa-video-camera" aria-hidden="true" title="Reshare Camera"></i>';
197 755
 				VideoShare.onclick = function() {
198 756
 					phone.ShareVideo();
199 757
 				};
200 758
 
201 759
 				controls.appendChild(VideoShare);
760
+
761
+                                // View all video windows in full screen
762
+				let allFullScreen = document.createElement("button");
763
+		                allFullScreen.className = "mediaControlBtn";
764
+		                allFullScreen.id = "fullscreen";
765
+				allFullScreen.innerHTML = '<i class="fa fa-arrows-alt" aria-hidden="true" title="Full Screen"></i>';
766
+		                allFullScreen.onclick = function() { toggleFullScreen(document.body); }
767
+
768
+				controls.appendChild(allFullScreen);
769
+
202 770
                         }
203 771
 
772
+                        // View this video window in full screen
204 773
                         let fullScreen = document.createElement("button");
205 774
                         fullScreen.className = "mediaControlBtn";
206
-                        fullScreen.innerHTML = '<i class="fa fa-expand" aria-hidden="true" title="Full Screen"></i>';
775
+                        fullScreen.innerHTML = '<i class="fa fa-window-maximize" aria-hidden="true" title="Expand Window"></i>';
207 776
 			fullScreen.onclick = function() {
208 777
 			    this.fullScreen.request();					
209 778
 			};
... ...
@@ -214,13 +783,11 @@ window.onload = function() {
214 783
 		return controls;
215 784
 	}
216 785
 
217
-
218 786
 	function createMediaView(stream) {
219 787
 
220
-		let mediaView = document.createElement("div");
788
+		var mediaView = document.createElement("div");
221 789
 		mediaView.className = "media-view";
222
-		mediaView.id = "new-media-view"+stream.id; // Makes it easy to find later
223
-                mediaView.style.width = localStorage.getItem("VidConfWindowWidth")+"%";
790
+		mediaView.id = "new-media-view"+stream.id;
224 791
 
225 792
 		let videoView = document.createElement("div");
226 793
                 videoView.className = "video-view";
... ...
@@ -230,28 +797,105 @@ window.onload = function() {
230 797
                 video.className = "videoElem";
231 798
                 video.id = "locVideo"+stream.id;
232 799
 		video.autoplay = true;
800
+
233 801
 		video.srcObject = stream;
802
+
234 803
 		video.onloadedmetadata = function() {
235 804
 
236 805
 		      let tracks = stream.getVideoTracks();
237
-
238 806
 		      for (let i = 0; i < tracks.length; ++i) {
239 807
 			   tracks[i].enabled = true;
240 808
 		      }
241
-
242 809
 		};
243 810
 
811
+                // Add participant's name at the bottom of the video window
812
+                var userDesc = document.createElement("div");
813
+                userDesc.className = "user-desc";
814
+                var userDescription = '';
815
+
816
+                // Add the video conference room label at the bottom-right corner of the video window
817
+                var confRoomLabel = document.createElement("div");
818
+                confRoomLabel.className = "vidConfLabel";
819
+                confRoomLabel.innerHTML = "Room: "+ videoConfTag;
820
+
821
+                // Add a green border over the video window of the person who is talking
822
+                var talkSignal = document.createElement("div");
823
+                talkSignal.className = "talkDetect";
824
+
244 825
 		if (stream.local == false) {
245 826
 
827
+                        let userDescCheck = 0;
828
+
246 829
 			function checkForVideo() {
247
-				if (video.videoWidth < 10 || video.videoHeight < 10) {
248
-                                    mediaView.style.display = 'none';
249
-				    return;
250
-				}
251
-                                mediaView.style.display = 'inline';
830
+
831
+                                mediaView.style.display = 'inline-block';
832
+
833
+                                // Get the 'profile name'/'user description' from the database
834
+		                var StreamID = stream.id;
835
+
836
+		                if (userDescCheck < 4 && StreamID != '' && StreamID != 'undefined' && StreamID != null) {
837
+
838
+					let gotChannelId = '';
839
+					for (let i = 0; i < StreamChanTbl.length; i++) {
840
+					     if (StreamChanTbl[i].streamId == StreamID) { gotChannelId = StreamChanTbl[i].channelId; }
841
+					}
842
+
843
+					let gotExtension = '';
844
+					for (let k = 0; k < ExtProNmTbl.length; k++) {
845
+                                             if (ExtProNmTbl[k].channelId == gotChannelId) { gotExtension = ExtProNmTbl[k].extension; }
846
+			                }
847
+
848
+                                        if (gotExtension != '') {
849
+
850
+                                            mediaView.setAttribute("name", "cmv_" + gotExtension);
851
+                                            talkSignal.id = "talk-detect-" + gotExtension;
852
+
853
+					    $.ajax({
854
+					        type: "POST",
855
+					        url: "../src/get-conf-user-description.php",
856
+					        dataType: "JSON",
857
+					        data: {
858
+						        clrextension: gotExtension,
859
+						        s_ajax_call: validateSToken
860
+					        },
861
+					        success: function(response) {
862
+				                      if (response.result == 'success') { 
863
+		                                          userDescription = response.userdescription;
864
+                                                          videoView.setAttribute("name", userDescription);
865
+
866
+                                                          if (userDescription != 'undefined' && userDescription != null) {
867
+
868
+                                                              let userNameDisplay = response.namedisplay;
869
+
870
+                                                              if (userNameDisplay == 1 && showConfUNames == 1 && userDescription != '' && userDescription != null) {
871
+	                                                          userDesc.innerHTML = '<span>' + userDescription  + '</span>';
872
+                                                                  videoView.appendChild(userDesc);
873
+                                                                  ++userDescCheck;
874
+                                                              }
875
+                                                          }                                            
876
+		                                      }
877
+					        },
878
+					        error: function(response) {
879
+						          alert("An error occurred while attempting to retrieve the profile name/user description from the database!");
880
+					        }
881
+					    });
882
+
883
+                                        }
884
+
885
+		                }
886
+
252 887
 			}
888
+
253 889
                         checkForVideo();
254 890
 			setInterval(checkForVideo, 1000);
891
+
892
+                        if (remoteCheck == 0) {
893
+                            // Hide our own remote video track
894
+                            remoteCheck = 1;
895
+                            document.getElementById(mediaView.id).style.display = 'none';
896
+
897
+                        }
898
+
255 899
 		}
256 900
 
257 901
 		// Video elements connected to local streams will by default
... ...
@@ -260,159 +904,69 @@ window.onload = function() {
260 904
 		// the audio portion.
261 905
 		if (stream.local == true) {
262 906
 			video.muted = true;
263
-		} else if (mvcount == 0) {
264
-			// We hide the video view until we receive video
265
-                        // We hide our own remote video track
266
-                        mvcount = 1;
267
-                        document.getElementById(mediaView.id).style.display = 'none'; 
268
-		}
907
+
908
+                        if (showConfUNames == 1) {
909
+
910
+                            userDesc.innerHTML = '<span>' + profileName + '</span>';
911
+                            videoView.appendChild(userDesc);
912
+                        }
913
+
914
+                        videoView.appendChild(confRoomLabel);
915
+                        mediaView.id = "new-media-view" + stream.id;
916
+                        mediaView.setAttribute("name", "cmv_" + crUserExt);
917
+                }
269 918
 
270 919
 		videoView.appendChild(video);
920
+                mediaView.appendChild(talkSignal);
271 921
 		mediaView.appendChild(videoView);
272
-		mediaView.appendChild(createMediaControls(video));
922
+                mediaView.appendChild(createMediaControls(video, stream.id));
273 923
 
274 924
 		return mediaView;
275 925
 	}
276 926
 
277
-	function removeMediaView(parent, stream) {
278
-		let node = findMediaView(parent, stream);
279
-		if (node) {
280
-			parent.removeChild(node);
281
-		}
282
-	}
283
-
284
-	function getValue(id) {
285
-		let obj = document.getElementById(id);
286
-		return obj.value ? obj.value : obj.placeholder;
287
-	}
288
-
289
-        $.ajax({
290
-            'async': false,
291
-            'global': false,
292
-            type: "POST",
293
-            url: "../get-sippass.php",
294
-            dataType: "JSON",
295
-            data: {
296
-                    username: userName,
297
-                    s_ajax_call: validateSToken
298
-            },
299
-            success: function (sipdatafromdb) {
300
-                           sipPassDec = sipdatafromdb;
301
-            },
302
-            error: function(sipdatafromdb) {
303
-                     alert("An error occurred while attempting to retrieve data from the database!");
304
-            }
305
-        });
306
-
307
-        document.getElementById("connect").addEventListener("click", function() {
308
-		if (document.getElementById("connect").value == "Disconnect") {
309
-			document.getElementById("call").value = "Call";
310
-			document.getElementById("call").disabled = true;
311
-			document.getElementById("connect").value = "Disconnecting";
312
-			document.getElementById("connect").disabled = true;
313
-
314
-			phone.disconnect();
315
-			return;
316
-		}
317
-
318
-                phone = new ConferencePhone(localStorage.getItem("SipUsername"), localStorage.getItem("SipUsername"), sipPassDec, localStorage.getItem("wssServer"), localStorage.getItem("StunServer"), true);
927
+	$.when(
928
+		$.ajax({
929
+		    type: "POST",
930
+		    url: "../src/get-sippass.php",
931
+		    dataType: "JSON",
932
+		    data: {
933
+		            username: userName,
934
+		            s_ajax_call: validateSToken
935
+		    },
936
+		    success: function (sipdatafromdb) {
937
+		                   sipPassDec = sipdatafromdb;
938
+		    },
939
+		    error: function(sipdatafromdb) {
940
+		             alert("An error occurred while attempting to retrieve data from the database!");
941
+		    }
942
+		})
943
+
944
+	).then(function() {
945
+
946
+                phone = new ConferencePhone(crUserExt, crUserExt, sipPassDec, wssServer, localStorage.getItem("StunServer"), true);
319 947
 
320 948
                 sipPassDec = '';
321 949
 
322
-		phone.handle("connected", function () {
323
-
324
-			if (document.getElementById("connect").value != "Disconnect") {
325
-				document.getElementById("connect").value = "Registering";
326
-			} else {
327
-				document.getElementById("connect").value = "Disconnect";
328
-				document.getElementById("connect").disabled = false;
329
-				document.getElementById("call").disabled = false;
330
-			}
331
-		});
332
-
333
-		phone.handle("disconnected", function () {
334
-			document.getElementById("connect").value = "Connect";
335
-			document.getElementById("connect").disabled = false;
336
-			document.getElementById("call").value = "Call";
337
-			document.getElementById("call").disabled = true;
338
-		});
339
-
340
-		phone.handle("registered", function () {
341
-			document.getElementById("connect").value = "Disconnect";
342
-			document.getElementById("connect").disabled = false;
343
-			document.getElementById("call").disabled = false;
344
-		});
345
-
346 950
 		phone.handle("registrationFailed", function () {
347 951
 			phone.disconnect();
348 952
 		});
349 953
 
350
-		phone.handle("incoming", function (reason) {
351
-			document.getElementById("call").value = "Answer";
352
-		});
353
-
354
-		phone.handle("failed", function (reason) {
355
-			document.getElementById("call").value = "Call";
356
-			document.getElementById("call").disabled = false;
357
-		});
358
-
359
-		phone.handle("ended", function (reason) {
360
-			document.getElementById("call").value = "Call";
361
-			document.getElementById("call").disabled = document.getElementById("connect").value == "Connect";
362
-		});
363
-
364 954
 		phone.handle("streamAdded", function (stream) {
365
-			document.getElementById("media-views").appendChild(createMediaView(stream));
366
-			document.getElementById("call").value = "Hangup";
367
-			document.getElementById("call").disabled = false;
368
-                        document.getElementById("call").style.display = 'inline';
369
-                        document.getElementById("fullscreen").style.display = 'inline';
370
-                        document.getElementById("fullscreen").innerHTML = '<i class="fa fa-expand" aria-hidden="true"></i><b>&nbsp; Fullscreen';
371
-		});
372 955
 
373
-		phone.handle("streamRemoved", function (stream) {
374
-			removeMediaView(document.getElementById("media-views"), stream);
956
+		        try { document.getElementById("media-views").appendChild(createMediaView(stream)); } catch(e) { return; }
957
+                        ++userCount;
958
+                        phone.resizeVideo(userCount);
375 959
 		});
376 960
 
377 961
 		phone.connect();
378
-
379
-		document.getElementById("connect").disabled = true;
380
-		document.getElementById("connect").value = "Connecting";
381 962
 	});
382 963
 
383
-        document.getElementById("connect").click();
384
-
385
-        let videoConfExtension = localStorage.getItem("VidConfExtension");
386 964
 
387 965
         let constraints = { audio: true, video: true };
388
-        navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
389
-            phone.call(videoConfExtension);
390
-        }).catch(function(err) { });
391 966
 
392
-        let node = document.getElementById("call");
393
-
394
-        if (node.value == "Answer") {
395
-	    node.disabled = true;
396
-	    node.value = "Hangup";
397
-	}
398
-
399
-        document.getElementById("call").addEventListener("click", function() {
400
-            if (node.value == "Hangup") {
401
-	        phone.terminate();
402
-                document.getElementById("call").remove();
403
-                window.close();
404
-            }
405
-        });
406
-
407
-	$("#showConnectionBttns").click(function() {
408
-	  if ($("#connection").is(':visible')) {
409
-	      $("#connection").hide();
410
-	      $("#showConnectionBttns").html('<i class="fa fa-caret-down" aria-hidden="true"></i>');
411
-	  } else { 
412
-	      $("#connection").show();
413
-	      $("#showConnectionBttns").html('<i class="fa fa-caret-up" aria-hidden="true"></i>');
414
-	  }
415
-	});
967
+        navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
968
+                  phone.call(videoConfExtension);
969
+        }).catch(function(err) { alert("Error getting media devices!"); });
416 970
 
417 971
 	document.addEventListener("fullscreenchange", onFullScreenChange, false);
418 972
 	document.addEventListener("webkitfullscreenchange", onFullScreenChange, false);
... ...
@@ -420,17 +974,39 @@ window.onload = function() {
420 974
 
421 975
 	function onFullScreenChange() {
422 976
 	   if (document.mozFullScreenElement != null || document.webkitFullscreenElement != null || document.fullscreenElement != null) {
423
-	       document.getElementById("fullscreen").innerHTML = '<i class="fa fa-compress" aria-hidden="true"></i><b>&nbsp; Exit Fullscreen';
424
-	       document.getElementById("fullscreen").style.width = "148px";
977
+               document.getElementById("fullscreen").style = "color: #0d60e1";
425 978
 	   } else { 
426
-	       document.getElementById("fullscreen").innerHTML = '<i class="fa fa-expand" aria-hidden="true"></i><b>&nbsp; Fullscreen';
427
-	       document.getElementById("fullscreen").style.width = "117px";
979
+               document.getElementById("fullscreen").style = "color: #000000";
428 980
 	   }
429 981
 	}
430 982
 
983
+
984
+        // Get the private key of the current video conference extension, since it may have been created previously by another conference participant
985
+        $.ajax({
986
+          type: "POST",
987
+          url: "../src/get-text-chat-vconf-priv-key.php",
988
+          dataType: "JSON",
989
+          data: {
990
+	     crntvconfext: videoConfExtension,
991
+             s_ajax_call: validateSToken
992
+          },
993
+          success: function(result) {
994
+
995
+                if (result.resmessage == 'success') {
996
+                    currentVconfPrivKey = "`" + result.chatprivkey.join("") + "`";
997
+                } else {
998
+                      alert('An error occurred while retrieving the private key for text chat!');
999
+                }
1000
+          },
1001
+          error: function(result) {
1002
+                      alert('An error occurred while attempting to retrieve the private key for text chat!');
1003
+          }
1004
+        });
1005
+
431 1006
 }; // window.onload
432 1007
 
433 1008
 window.onbeforeunload = function() {
1009
+       localStorage.setItem('vConfOpenCheck', 'closed');
434 1010
        phone.terminate();
435 1011
 }; 
436 1012
 
... ...
@@ -439,18 +1015,12 @@ window.onunload = function() {
439 1015
 	   phone.disconnect();
440 1016
        }
441 1017
 }; // window.onunload
1018
+
442 1019
 </script>
443 1020
 </head>
444 1021
 <body>
445
-	<div id="connection">
446
-               <div id="VideoConferenceLogo"><img src="../images/small-logo.svg" /></div>
447
-	       <input type="button" id="connect" class="connect" value="Connect" style="display:none;" />
448
-               <button id="call" class="call"><i class="fa fa-phone" aria-hidden="true"></i><b>&nbsp; Hangup</b></button>
449
-               <button id="fullscreen" class="fullscreen" onclick="toggleFullScreen(document.body)"><i class="fa fa-expand" aria-hidden="true"></i><b>&nbsp; Fullscreen</b></button>
450
-	</div>
451
-        <div id="showConnectionBttns"><i class="fa fa-caret-down" aria-hidden="true"></i></div>
452
-
453
-	<div id="media-views" class="media-views"></div>
1022
+  <input type="button" id="connect" class="connect" value="Connect" style="display: none;" />
1023
+  <div id="media-frame"><div id="media-views" class="media-views"></div></div>
454 1024
 
455 1025
 <script type="text/javascript">
456 1026
 
... ...
@@ -499,13 +1069,6 @@ function toggleFullScreen(elem) {
499 1069
     }
500 1070
 }
501 1071
 
502
-window.onclick = function(event) {
503
-	let modal = document.getElementById("account-modal");
504
-	if (event.target == modal) {
505
-		modal.style.display = "none";
506
-	}
507
-}
508
-
509 1072
 </script>
510 1073
 </body>
511 1074
 </html>
... ...
@@ -513,7 +1076,7 @@ window.onclick = function(event) {
513 1076
 <?php
514 1077
 
515 1078
 } else {
516
-     header("Location: ../roundpin-login.php");
517
-  }
1079
+     header("Location: ../login.php");
1080
+}
518 1081
 
519
-?>
520 1082
\ No newline at end of file
1083
+?>
Browse code

Created repository.

DoubleBastionAdmin authored on 26/01/2022 20:32:42
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,519 @@
1
+<?php
2
+/**
3
+ *  Copyright (C) 2021  Double Bastion LLC
4
+ *
5
+ *  This file is part of Roundpin, which is licensed under the
6
+ *  GNU Affero General Public License Version 3.0. The license terms
7
+ *  are detailed in the "LICENSE.txt" file located in the root directory.
8
+ *
9
+ *  This is a modified version of the original file "index.html",
10
+ *  first modified in 2020. The copyright notice for the original
11
+ *  content follows:
12
+
13
+/*
14
+  Cyber Mega Phone 2K
15
+  Copyright (C) 2017 Digium, Inc.
16
+
17
+  This program is free software, distributed under the terms of the
18
+  MIT License. See the LICENSE file at the top of the source tree.
19
+*/
20
+
21
+session_start();
22
+
23
+if ($_SESSION['loggedtoroundpin'] == true) {
24
+
25
+?>
26
+
27
+<script type="text/javascript">
28
+    let validateSToken = "<?php print_r($_SESSION['validate_s_access']); ?>";
29
+    let userName = "<?php print_r($_SESSION['loginname']); ?>";
30
+</script>
31
+
32
+<!DOCTYPE html>
33
+
34
+<html>
35
+<head>
36
+	<meta charset="utf-8" />
37
+	<title>Roundpin Video Conference</title>
38
+	<link rel="stylesheet" type="text/css" href="css/conference-phone.min.css">
39
+        <link rel="stylesheet" type="text/css" href="../fonts/font-awesome-4.7.0/css/font-awesome.min.css"/>
40
+
41
+        <link rel="stylesheet" type="text/css" href="../css/jeegoo-1.0.0.min.css"/>
42
+
43
+        <link rel="shortcut icon" type="image/svg" href="../images/favicon.svg" />
44
+	<script type="text/javascript" src="js/sdp-interop-sl-1.4.0.min.js"></script>
45
+        <script type="text/javascript" src="js/jssip-3.7.0.min.js"></script>
46
+	<script type="text/javascript" src="js/utils.min.js"></script>
47
+        <script type="text/javascript" src="../js/jquery-3.3.1.min.js"></script>
48
+
49
+	<script type="text/javascript" src="js/conference-phone.min.js"></script>
50
+
51
+        <script type="text/javascript" src="../js/jquery.jeegoopopup.1.0.0.min.js"></script>
52
+
53
+<script type="text/javascript">
54
+
55
+let phone;
56
+let numPressed = null;
57
+
58
+window.onload = function() {
59
+
60
+        var mvcount = 0;
61
+        var sipPassDec = '';
62
+
63
+	document.getElementById("connect").value = "Connect";
64
+	document.getElementById("connect").disabled = false;
65
+	document.getElementById("call").value = "Call";
66
+	document.getElementById("call").disabled = true;
67
+        document.getElementById("call").style.display = 'none';
68
+        document.getElementById("fullscreen").style.display = 'none';
69
+
70
+	function findMediaView(parent, stream) {
71
+		let nodes = parent.childNodes;
72
+
73
+		for (let i = 0; i < nodes.length; ++i) {
74
+			if (nodes[i].id == stream.id) {
75
+				return nodes[i];
76
+			}
77
+		}
78
+		return null;
79
+	}
80
+
81
+        function dtmfMenuShow() {
82
+
83
+                $.jeegoopopup.close();
84
+
85
+	        var leftPos = event.pageX - 90;
86
+	        var topPos = event.pageY + 28;
87
+
88
+		if ($(window).width() < 680) {
89
+		    leftPos = event.pageX - 50;
90
+		}
91
+
92
+	        var html = "<div id=\"sendPinDialPad\">";
93
+	        html += "<div><input type=\"text\" id=\"dialText\" class=\"dialTextInput\"></div>";
94
+	        html += "<table cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">";
95
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('1');new Audio('../sounds/dtmf.mp3').play();\"><div>1</div><span>&nbsp;</span></button></td>";
96
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('2');new Audio('../sounds/dtmf.mp3').play();\"><div>2</div><span>ABC</span></button></td>";
97
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('3');new Audio('../sounds/dtmf.mp3').play();\"><div>3</div><span>DEF</span></button></td></tr>";
98
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('4');new Audio('../sounds/dtmf.mp3').play();\"><div>4</div><span>GHI</span></button></td>";
99
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('5');new Audio('../sounds/dtmf.mp3').play();\"><div>5</div><span>JKL</span></button></td>";
100
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('6');new Audio('../sounds/dtmf.mp3').play();\"><div>6</div><span>MNO</span></button></td></tr>";
101
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('7');new Audio('../sounds/dtmf.mp3').play();\"><div>7</div><span>PQRS</span></button></td>";
102
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('8');new Audio('../sounds/dtmf.mp3').play();\"><div>8</div><span>TUV</span></button></td>";
103
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('9');new Audio('../sounds/dtmf.mp3').play();\"><div>9</div><span>WXYZ</span></button></td></tr>";
104
+	        html += "<tr><td><button class=dtmfButtons onclick=\"phone.dtmfSend('*');new Audio('../sounds/dtmf.mp3').play();\">*</button></td>";
105
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('0');new Audio('../sounds/dtmf.mp3').play();\">0</button></td>";
106
+	        html += "<td><button class=dtmfButtons onclick=\"phone.dtmfSend('#');new Audio('../sounds/dtmf.mp3').play();\">#</button></td></tr>";
107
+	        html += "</table>";
108
+	        html += "</div>";
109
+
110
+	        $.jeegoopopup.open({
111
+			html: html,
112
+			width: "auto",
113
+			height: "auto",
114
+			left: leftPos,
115
+			top: topPos,
116
+			scrolling: 'no',
117
+			skinClass: 'jg_popup_basic',
118
+			overlay: true,
119
+			opacity: 0,
120
+			draggable: true,
121
+			resizable: false,
122
+			fadeIn: 0
123
+	        });
124
+
125
+	        $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); });
126
+	        $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } });
127
+        }
128
+
129
+	function createMediaControls(video) {
130
+
131
+		let controls = document.createElement("div");
132
+		controls.className = "media-controls";
133
+
134
+                if (video.srcObject.local == true) {
135
+		        let sendPin = document.createElement("button");
136
+                        sendPin.className = "mediaControlBtn";
137
+                        sendPin.id = "sendPinBtn";
138
+		        sendPin.innerHTML = '<i class="fa fa-keyboard-o" aria-hidden="true" title="Show Keypad"></i>';
139
+                        sendPin.onclick = function() { dtmfMenuShow(); }
140
+
141
+		        controls.appendChild(sendPin);
142
+                }
143
+
144
+		let audioTracks = video.srcObject.getAudioTracks();
145
+		if (audioTracks.length > 0) {
146
+                        let muteAudio = document.createElement("button");
147
+                        muteAudio.className = "mediaControlBtn";
148
+                        muteAudio.innerHTML = '<i class="fa fa-microphone-slash" aria-hidden="true" title="Mute Audio"></i>';
149
+			muteAudio.setAttribute("state", "Unmute");
150
+			muteAudio.onclick = function() {
151
+				let state = this.getAttribute("state");
152
+                                if (state == "Mute") {
153
+                                    this.setAttribute("state", "Unmute");
154
+                                    this.innerHTML = '<i class="fa fa-microphone-slash" aria-hidden="true" title="Mute Audio"></i>';
155
+                                } else if (state == "Unmute") {
156
+                                    this.setAttribute("state", "Mute");
157
+                                    this.innerHTML = '<i class="fa fa-microphone" aria-hidden="true" title="Unmute Audio"></i>';
158
+                                }
159
+				mute(video.srcObject, {audio: this.getAttribute("state") == "Mute"});
160
+			};
161
+			controls.appendChild(muteAudio);
162
+		}
163
+
164
+		let videoTracks = video.srcObject.getVideoTracks();
165
+		if (videoTracks.length > 0) {
166
+                        let muteVideo = document.createElement("button");
167
+                        muteVideo.className = "mediaControlBtn";
168
+                        muteVideo.innerHTML = '<i class="fa fa-ban" aria-hidden="true" title="Mute Video"></i>';
169
+			muteVideo.setAttribute("state", "Unmute");
170
+			muteVideo.onclick = function() {
171
+				let state = this.getAttribute("state");
172
+                                if (state == "Mute") {
173
+                                    this.setAttribute("state", "Unmute");
174
+                                    this.innerHTML = '<i class="fa fa-ban" aria-hidden="true" title="Mute Video"></i>';
175
+                                } else if (state == "Unmute") {
176
+                                    this.setAttribute("state", "Mute");
177
+                                    this.innerHTML = '<i class="fa fa-video-camera" aria-hidden="true" title="Unmute Video"></i>';
178
+                                }
179
+
180
+				mute(video.srcObject, {video: this.getAttribute("state") == "Mute"});
181
+			};
182
+			controls.appendChild(muteVideo);
183
+
184
+                        if (video.srcObject.local == true) {
185
+                                let ScreenShare = document.createElement("button");
186
+                                ScreenShare.className = "mediaControlBtn";
187
+                                ScreenShare.innerHTML = '<i class="fa fa-desktop" aria-hidden="true" title="Share Screen"></i>';
188
+				ScreenShare.onclick = function() {
189
+					phone.ShareScreen();
190
+				};
191
+
192
+				controls.appendChild(ScreenShare);
193
+
194
+                                let VideoShare = document.createElement("button");
195
+                                VideoShare.className = "mediaControlBtn";
196
+                                VideoShare.innerHTML = '<i class="fa fa-video-camera" aria-hidden="true" title="Share Camera"></i>';
197
+				VideoShare.onclick = function() {
198
+					phone.ShareVideo();
199
+				};
200
+
201
+				controls.appendChild(VideoShare);
202
+                        }
203
+
204
+                        let fullScreen = document.createElement("button");
205
+                        fullScreen.className = "mediaControlBtn";
206
+                        fullScreen.innerHTML = '<i class="fa fa-expand" aria-hidden="true" title="Full Screen"></i>';
207
+			fullScreen.onclick = function() {
208
+			    this.fullScreen.request();					
209
+			};
210
+
211
+			fullScreen.fullScreen = new FullScreen(video);
212
+			controls.appendChild(fullScreen);
213
+		}
214
+		return controls;
215
+	}
216
+
217
+
218
+	function createMediaView(stream) {
219
+
220
+		let mediaView = document.createElement("div");
221
+		mediaView.className = "media-view";
222
+		mediaView.id = "new-media-view"+stream.id; // Makes it easy to find later
223
+                mediaView.style.width = localStorage.getItem("VidConfWindowWidth")+"%";
224
+
225
+		let videoView = document.createElement("div");
226
+                videoView.className = "video-view";
227
+                videoView.id = "video-view"+stream.id;
228
+
229
+		let video = document.createElement("video");
230
+                video.className = "videoElem";
231
+                video.id = "locVideo"+stream.id;
232
+		video.autoplay = true;
233
+		video.srcObject = stream;
234
+		video.onloadedmetadata = function() {
235
+
236
+		      let tracks = stream.getVideoTracks();
237
+
238
+		      for (let i = 0; i < tracks.length; ++i) {
239
+			   tracks[i].enabled = true;
240
+		      }
241
+
242
+		};
243
+
244
+		if (stream.local == false) {
245
+
246
+			function checkForVideo() {
247
+				if (video.videoWidth < 10 || video.videoHeight < 10) {
248
+                                    mediaView.style.display = 'none';
249
+				    return;
250
+				}
251
+                                mediaView.style.display = 'inline';
252
+			}
253
+                        checkForVideo();
254
+			setInterval(checkForVideo, 1000);
255
+		}
256
+
257
+		// Video elements connected to local streams will by default
258
+		// echo both the video and the audio back to ourselves. Since
259
+		// we don't want to hear ourselves we mute it, which mutes only
260
+		// the audio portion.
261
+		if (stream.local == true) {
262
+			video.muted = true;
263
+		} else if (mvcount == 0) {
264
+			// We hide the video view until we receive video
265
+                        // We hide our own remote video track
266
+                        mvcount = 1;
267
+                        document.getElementById(mediaView.id).style.display = 'none'; 
268
+		}
269
+
270
+		videoView.appendChild(video);
271
+		mediaView.appendChild(videoView);
272
+		mediaView.appendChild(createMediaControls(video));
273
+
274
+		return mediaView;
275
+	}
276
+
277
+	function removeMediaView(parent, stream) {
278
+		let node = findMediaView(parent, stream);
279
+		if (node) {
280
+			parent.removeChild(node);
281
+		}
282
+	}
283
+
284
+	function getValue(id) {
285
+		let obj = document.getElementById(id);
286
+		return obj.value ? obj.value : obj.placeholder;
287
+	}
288
+
289
+        $.ajax({
290
+            'async': false,
291
+            'global': false,
292
+            type: "POST",
293
+            url: "../get-sippass.php",
294
+            dataType: "JSON",
295
+            data: {
296
+                    username: userName,
297
+                    s_ajax_call: validateSToken
298
+            },
299
+            success: function (sipdatafromdb) {
300
+                           sipPassDec = sipdatafromdb;
301
+            },
302
+            error: function(sipdatafromdb) {
303
+                     alert("An error occurred while attempting to retrieve data from the database!");
304
+            }
305
+        });
306
+
307
+        document.getElementById("connect").addEventListener("click", function() {
308
+		if (document.getElementById("connect").value == "Disconnect") {
309
+			document.getElementById("call").value = "Call";
310
+			document.getElementById("call").disabled = true;
311
+			document.getElementById("connect").value = "Disconnecting";
312
+			document.getElementById("connect").disabled = true;
313
+
314
+			phone.disconnect();
315
+			return;
316
+		}
317
+
318
+                phone = new ConferencePhone(localStorage.getItem("SipUsername"), localStorage.getItem("SipUsername"), sipPassDec, localStorage.getItem("wssServer"), localStorage.getItem("StunServer"), true);
319
+
320
+                sipPassDec = '';
321
+
322
+		phone.handle("connected", function () {
323
+
324
+			if (document.getElementById("connect").value != "Disconnect") {
325
+				document.getElementById("connect").value = "Registering";
326
+			} else {
327
+				document.getElementById("connect").value = "Disconnect";
328
+				document.getElementById("connect").disabled = false;
329
+				document.getElementById("call").disabled = false;
330
+			}
331
+		});
332
+
333
+		phone.handle("disconnected", function () {
334
+			document.getElementById("connect").value = "Connect";
335
+			document.getElementById("connect").disabled = false;
336
+			document.getElementById("call").value = "Call";
337
+			document.getElementById("call").disabled = true;
338
+		});
339
+
340
+		phone.handle("registered", function () {
341
+			document.getElementById("connect").value = "Disconnect";
342
+			document.getElementById("connect").disabled = false;
343
+			document.getElementById("call").disabled = false;
344
+		});
345
+
346
+		phone.handle("registrationFailed", function () {
347
+			phone.disconnect();
348
+		});
349
+
350
+		phone.handle("incoming", function (reason) {
351
+			document.getElementById("call").value = "Answer";
352
+		});
353
+
354
+		phone.handle("failed", function (reason) {
355
+			document.getElementById("call").value = "Call";
356
+			document.getElementById("call").disabled = false;
357
+		});
358
+
359
+		phone.handle("ended", function (reason) {
360
+			document.getElementById("call").value = "Call";
361
+			document.getElementById("call").disabled = document.getElementById("connect").value == "Connect";
362
+		});
363
+
364
+		phone.handle("streamAdded", function (stream) {
365
+			document.getElementById("media-views").appendChild(createMediaView(stream));
366
+			document.getElementById("call").value = "Hangup";
367
+			document.getElementById("call").disabled = false;
368
+                        document.getElementById("call").style.display = 'inline';
369
+                        document.getElementById("fullscreen").style.display = 'inline';
370
+                        document.getElementById("fullscreen").innerHTML = '<i class="fa fa-expand" aria-hidden="true"></i><b>&nbsp; Fullscreen';
371
+		});
372
+
373
+		phone.handle("streamRemoved", function (stream) {
374
+			removeMediaView(document.getElementById("media-views"), stream);
375
+		});
376
+
377
+		phone.connect();
378
+
379
+		document.getElementById("connect").disabled = true;
380
+		document.getElementById("connect").value = "Connecting";
381
+	});
382
+
383
+        document.getElementById("connect").click();
384
+
385
+        let videoConfExtension = localStorage.getItem("VidConfExtension");
386
+
387
+        let constraints = { audio: true, video: true };
388
+        navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
389
+            phone.call(videoConfExtension);
390
+        }).catch(function(err) { });
391
+
392
+        let node = document.getElementById("call");
393
+
394
+        if (node.value == "Answer") {
395
+	    node.disabled = true;
396
+	    node.value = "Hangup";
397
+	}
398
+
399
+        document.getElementById("call").addEventListener("click", function() {
400
+            if (node.value == "Hangup") {
401
+	        phone.terminate();
402
+                document.getElementById("call").remove();
403
+                window.close();
404
+            }
405
+        });
406
+
407
+	$("#showConnectionBttns").click(function() {
408
+	  if ($("#connection").is(':visible')) {
409
+	      $("#connection").hide();
410
+	      $("#showConnectionBttns").html('<i class="fa fa-caret-down" aria-hidden="true"></i>');
411
+	  } else { 
412
+	      $("#connection").show();
413
+	      $("#showConnectionBttns").html('<i class="fa fa-caret-up" aria-hidden="true"></i>');
414
+	  }
415
+	});
416
+
417
+	document.addEventListener("fullscreenchange", onFullScreenChange, false);
418
+	document.addEventListener("webkitfullscreenchange", onFullScreenChange, false);
419
+	document.addEventListener("mozfullscreenchange", onFullScreenChange, false);
420
+
421
+	function onFullScreenChange() {
422
+	   if (document.mozFullScreenElement != null || document.webkitFullscreenElement != null || document.fullscreenElement != null) {
423
+	       document.getElementById("fullscreen").innerHTML = '<i class="fa fa-compress" aria-hidden="true"></i><b>&nbsp; Exit Fullscreen';
424
+	       document.getElementById("fullscreen").style.width = "148px";
425
+	   } else { 
426
+	       document.getElementById("fullscreen").innerHTML = '<i class="fa fa-expand" aria-hidden="true"></i><b>&nbsp; Fullscreen';
427
+	       document.getElementById("fullscreen").style.width = "117px";
428
+	   }
429
+	}
430
+
431
+}; // window.onload
432
+
433
+window.onbeforeunload = function() {
434
+       phone.terminate();
435
+}; 
436
+
437
+window.onunload = function() {
438
+       if (phone) {
439
+	   phone.disconnect();
440
+       }
441
+}; // window.onunload
442
+</script>
443
+</head>
444
+<body>
445
+	<div id="connection">
446
+               <div id="VideoConferenceLogo"><img src="../images/small-logo.svg" /></div>
447
+	       <input type="button" id="connect" class="connect" value="Connect" style="display:none;" />
448
+               <button id="call" class="call"><i class="fa fa-phone" aria-hidden="true"></i><b>&nbsp; Hangup</b></button>
449
+               <button id="fullscreen" class="fullscreen" onclick="toggleFullScreen(document.body)"><i class="fa fa-expand" aria-hidden="true"></i><b>&nbsp; Fullscreen</b></button>
450
+	</div>
451
+        <div id="showConnectionBttns"><i class="fa fa-caret-down" aria-hidden="true"></i></div>
452
+
453
+	<div id="media-views" class="media-views"></div>
454
+
455
+<script type="text/javascript">
456
+
457
+FullScreen.prototype.request = function() {
458
+	if (this.is()) {
459
+		return;
460
+	}
461
+
462
+	if (this._obj.requestFullscreen) {
463
+		this._obj.requestFullscreen();
464
+	} else if (this._obj.mozRequestFullScreen) {
465
+		this._obj.mozRequestFullScreen();
466
+	} else if (this._obj.webkitRequestFullScreen) {
467
+		this._obj.webkitRequestFullScreen();
468
+	} else if (this._obj.msRequestFullscreen) {
469
+		this._obj.msRequestFullscreen();
470
+	}
471
+
472
+	this.setData(true);
473
+};
474
+
475
+function toggleFullScreen(elem) {
476
+
477
+    if ((document.fullScreenElement !== undefined && document.fullScreenElement === null) || (document.msFullscreenElement !== undefined && document.msFullscreenElement === null) ||
478
+       (document.mozFullScreen !== undefined && !document.mozFullScreen) || (document.webkitIsFullScreen !== undefined && !document.webkitIsFullScreen)) {
479
+        if (elem.requestFullScreen) {
480
+            elem.requestFullScreen();
481
+        } else if (elem.mozRequestFullScreen) {
482
+            elem.mozRequestFullScreen();
483
+        } else if (elem.webkitRequestFullScreen) {
484
+            elem.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
485
+        } else if (elem.msRequestFullscreen) {
486
+            elem.msRequestFullscreen();
487
+        }
488
+
489
+    } else {
490
+        if (document.cancelFullScreen) {
491
+            document.cancelFullScreen();
492
+        } else if (document.mozCancelFullScreen) {
493
+            document.mozCancelFullScreen();
494
+        } else if (document.webkitCancelFullScreen) {
495
+            document.webkitCancelFullScreen();
496
+        } else if (document.msExitFullscreen) {
497
+            document.msExitFullscreen();
498
+        }
499
+    }
500
+}
501
+
502
+window.onclick = function(event) {
503
+	let modal = document.getElementById("account-modal");
504
+	if (event.target == modal) {
505
+		modal.style.display = "none";
506
+	}
507
+}
508
+
509
+</script>
510
+</body>
511
+</html>
512
+
513
+<?php
514
+
515
+} else {
516
+     header("Location: ../roundpin-login.php");
517
+  }
518
+
519
+?>
0 520
\ No newline at end of file