1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,19 @@ |
1 |
+ |
|
2 |
+======= CHANGELOG ======= |
|
3 |
+ |
|
4 |
+Versions: |
|
5 |
+ |
|
6 |
+== 1.0.0 - 2022-1-27 == |
|
7 |
+* Initial Release. |
|
8 |
+ |
|
9 |
+== 1.0.1 - 2022-3-26 == |
|
10 |
+* Fixed error message on logout. |
|
11 |
+ |
|
12 |
+== 1.0.2 - 2022-3-28 == |
|
13 |
+* Small text changes in README.md. |
|
14 |
+ |
|
15 |
+== 1.0.3 - 2022-4-9 == |
|
16 |
+* Fixed sign up bug and changed the app presentation text. |
|
17 |
+ |
|
18 |
+== 1.0.4 - 2022-5-11 == |
|
19 |
+* Removed sign out warning related to Roundpin logout. |
0 | 20 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,18 @@ |
1 |
+ |
|
2 |
+========================== CONTRIBUTORS ========================== |
|
3 |
+ |
|
4 |
+"Roundpin" includes large portions from "Browser Phone", developed |
|
5 |
+by Conrad de Wet, and large portions from "Cyber Mega Phone 2k", |
|
6 |
+developed by Digium, Inc. We once again thank them for their |
|
7 |
+amazing work and for licensing their software in a way that |
|
8 |
+promotes user freedom and collaboration. We also thank all |
|
9 |
+the developers who created the other pieces of software that |
|
10 |
+we included in "Roundpin". They are all mentioned, along with |
|
11 |
+the appropriate copyright notice, in the LICENSE.txt file |
|
12 |
+located in the root directory. |
|
13 |
+ |
|
14 |
+ |
|
15 |
+Double Bastion LLC is the leader of the "Roundpin" project |
|
16 |
+and the main contributor. We'll list below all the other |
|
17 |
+developers who will contribute to "Roundpin". |
|
18 |
+ |
0 | 19 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,12550 @@ |
1 |
+/** |
|
2 |
+ * Copyright (C) 2021 Double Bastion LLC |
|
3 |
+ * |
|
4 |
+ * This file is part of Roundpin, which is licensed under the |
|
5 |
+ * GNU Affero General Public License Version 3.0. The license terms |
|
6 |
+ * are detailed in the "LICENSE.txt" file located in the root directory. |
|
7 |
+ * |
|
8 |
+ * This is a modified version of the original file |
|
9 |
+ * "phone.js", first modified in 2020. |
|
10 |
+ * |
|
11 |
+ * The original "phone.js" file was written by Conrad de Wet. |
|
12 |
+ * We thank Conrad de Wet for his work and we list below |
|
13 |
+ * the copyright notice of the original "phone.js" file: |
|
14 |
+ |
|
15 |
+/* |
|
16 |
+------------------------------------------------------------- |
|
17 |
+ Copyright (c) 2020 - Conrad de Wet - All Rights Reserved. |
|
18 |
+============================================================= |
|
19 |
+File: phone.js |
|
20 |
+License: GNU Affero General Public License v3.0 |
|
21 |
+Version: 0.1.0 |
|
22 |
+Owner: Conrad de Wet |
|
23 |
+Date: April 2020 |
|
24 |
+Git: https://github.com/InnovateAsterisk/Browser-Phone |
|
25 |
+*/ |
|
26 |
+ |
|
27 |
+// Global Settings |
|
28 |
+// =============== |
|
29 |
+var enabledExtendedServices = false; |
|
30 |
+var enabledGroupServices = false; |
|
31 |
+ |
|
32 |
+// Lanaguage Packs (lang/xx.json) |
|
33 |
+// =============== |
|
34 |
+// Note: The following should correspond to files on your server. |
|
35 |
+// eg: If you list "fr" then you need to add the file "fr.json". |
|
36 |
+// Use the "en.json" as a template. |
|
37 |
+// More specific lanagauge must be first. ie: "zh-hans" should be before "zh". |
|
38 |
+// "en.json" is always loaded by default |
|
39 |
+const availableLang = ["ja", "zh-hans", "zh", "ru", "tr", "nl"]; |
|
40 |
+ |
|
41 |
+// User Settings & Defaults |
|
42 |
+// ======================== |
|
43 |
+var wssServer = getDbItem("wssServer", null); |
|
44 |
+var profileUserID = getDbItem("profileUserID", null); |
|
45 |
+var profileUser = getDbItem("profileUser", null); |
|
46 |
+var profileName = getDbItem("profileName", null); |
|
47 |
+var WebSocketPort = getDbItem("WebSocketPort", null); |
|
48 |
+var ServerPath = getDbItem("ServerPath", null); |
|
49 |
+var SipUsername = getDbItem("SipUsername", null); |
|
50 |
+var SipPassword = getDbItem("SipPassword", null); |
|
51 |
+var StunServer = getDbItem("StunServer", ""); |
|
52 |
+ |
|
53 |
+var TransportConnectionTimeout = parseInt(getDbItem("TransportConnectionTimeout", 15)); // The timeout in seconds for the initial connection to make on the web socket port |
|
54 |
+var TransportReconnectionAttempts = parseInt(getDbItem("TransportReconnectionAttempts", 99)); // The number of times to attempt to reconnect to a WebSocket when the connection drops. |
|
55 |
+var TransportReconnectionTimeout = parseInt(getDbItem("TransportReconnectionTimeout", 15)); // The time in seconds to wait between WebSocket reconnection attempts. |
|
56 |
+ |
|
57 |
+var userAgentStr = getDbItem("UserAgentStr", "Roundpin (SipJS - 0.11.6)"); // Set this to whatever you want. |
|
58 |
+var hostingPrefex = getDbItem("HostingPrefex", ""); // Use if hosting off root directiory. eg: "/phone/" or "/static/" |
|
59 |
+var RegisterExpires = parseInt(getDbItem("RegisterExpires", 300)); // Registration expiry time (in seconds) |
|
60 |
+var WssInTransport = (getDbItem("WssInTransport", "1") == "1"); // Set the transport parameter to wss when used in SIP URIs. (Required for Asterisk as it doesnt support Path) |
|
61 |
+var IpInContact = (getDbItem("IpInContact", "1") == "1"); // Set a random IP address as the host value in the Contact header field and Via sent-by parameter. (Suggested for Asterisk) |
|
62 |
+var IceStunCheckTimeout = parseInt(getDbItem("IceStunCheckTimeout", 500)); // Set amount of time in milliseconds to wait for the ICE/STUN server |
|
63 |
+var AutoAnswerEnabled = (getDbItem("AutoAnswerEnabled", "0") == "1"); // Automatically answers the phone when the call comes in, if you are not on a call already |
|
64 |
+var DoNotDisturbEnabled = (getDbItem("DoNotDisturbEnabled", "0") == "1"); // Rejects any inbound call, while allowing outbound calls |
|
65 |
+var CallWaitingEnabled = (getDbItem("CallWaitingEnabled", "1") == "1"); // Rejects any inbound call if you are on a call already. |
|
66 |
+var RecordAllCalls = (getDbItem("RecordAllCalls", "0") == "1"); // Starts Call Recording when a call is established. |
|
67 |
+var StartVideoFullScreen = (getDbItem("StartVideoFullScreen", "1") == "0"); // Starts a vdeo call in the full screen (browser screen, not dektop) |
|
68 |
+var AutoGainControl = (getDbItem("AutoGainControl", "1") == "1"); // Attempts to adjust the microphone volume to a good audio level. (OS may be better at this) |
|
69 |
+var EchoCancellation = (getDbItem("EchoCancellation", "1") == "1"); // Attemots to remove echo over the line. |
|
70 |
+var NoiseSuppression = (getDbItem("NoiseSuppression", "1") == "1"); // Attempts to clear the call qulity of noise. |
|
71 |
+var MirrorVideo = getDbItem("VideoOrientation", "rotateY(180deg)"); // Displays the self-preview in normal or mirror view, to better present the preview. |
|
72 |
+var maxFrameRate = getDbItem("FrameRate", ""); // Suggests a frame rate to your webcam if possible. |
|
73 |
+var videoHeight = getDbItem("VideoHeight", ""); // Suggests a video height (and therefore picture quality) to your webcam. |
|
74 |
+var videoAspectRatio = getDbItem("AspectRatio", ""); // Suggests an aspect ratio (1:1 | 4:3 | 16:9) to your webcam. |
|
75 |
+var NotificationsActive = (getDbItem("Notifications", "0") == "1"); |
|
76 |
+var StreamBuffer = parseInt(getDbItem("StreamBuffer", 50)); // The amount of rows to buffer in the Buddy Stream |
|
77 |
+var PosterJpegQuality = parseFloat(getDbItem("PosterJpegQuality", 0.6)); // The image quality of the Video Poster images |
|
78 |
+var VideoResampleSize = getDbItem("VideoResampleSize", "HD"); // The resample size (height) to re-render video that gets presented (sent). (SD = ???x360 | HD = ???x720 | FHD = ???x1080) |
|
79 |
+var RecordingVideoSize = getDbItem("RecordingVideoSize", "HD"); // The size/quality of the video track in the recodings (SD = 640x360 | HD = 1280x720 | FHD = 1920x1080) |
|
80 |
+var RecordingVideoFps = parseInt(getDbItem("RecordingVideoFps", 12)); // The Frame Per Second of the Video Track recording |
|
81 |
+var RecordingLayout = getDbItem("RecordingLayout", "them-pnp"); // The Layout of the Recording Video Track (side-by-side | us-pnp | them-pnp | us-only | them-only) |
|
82 |
+var DidLength = parseInt(getDbItem("DidLength", 6)); // DID length from which to decide if an incoming caller is a "contact" or an "extension". |
|
83 |
+var MaxDidLength = parseInt(getDbItem("maximumNumberLength", 16)); // Maximum langth of any DID number including international dialled numbers. |
|
84 |
+var DisplayDateFormat = getDbItem("DateFormat", "YYYY-MM-DD"); // The display format for all dates. https://momentjs.com/docs/#/displaying/ |
|
85 |
+var DisplayTimeFormat = getDbItem("TimeFormat", "h:mm:ss A"); // The display format for all times. https://momentjs.com/docs/#/displaying/ |
|
86 |
+var Language = getDbItem("Language", "auto"); // Overrides the langauage selector or "automatic". Must be one of availableLang[]. If not defaults to en. Testing: zh-Hans-CN, zh-cmn-Hans-CN, zh-Hant, de, de-DE, en-US, fr, fr-FR, es-ES, sl-IT-nedis, hy-Latn-IT-arevela |
|
87 |
+ |
|
88 |
+// Permission Settings |
|
89 |
+var EnableTextMessaging = (getDbItem("EnableTextMessaging", "1") == "1"); // Enables the Text Messaging |
|
90 |
+var DisableFreeDial = (getDbItem("DisableFreeDial", "0") == "1"); // Removes the Dial icon in the profile area, users will need to add buddies in order to dial. |
|
91 |
+var DisableBuddies = (getDbItem("DisableBuddies", "0") == "1"); // Removes the Add Someone menu item and icon from the profile area. Buddies will still be created automatically. |
|
92 |
+var EnableTransfer = (getDbItem("EnableTransfer", "1") == "1"); // Controls Transfering during a call |
|
93 |
+var EnableConference = (getDbItem("EnableConference", "1") == "1"); // Controls Conference during a call |
|
94 |
+var AutoAnswerPolicy = getDbItem("AutoAnswerPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on |
|
95 |
+var DoNotDisturbPolicy = getDbItem("DoNotDisturbPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on |
|
96 |
+var CallWaitingPolicy = getDbItem("CallWaitingPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on |
|
97 |
+var CallRecordingPolicy = getDbItem("CallRecordingPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on |
|
98 |
+var EnableAccountSettings = (getDbItem("EnableAccountSettings", "1") == "1"); // Controls the Account tab in Settings |
|
99 |
+var EnableAudioVideoSettings = (getDbItem("EnableAudioVideoSettings", "1") == "1"); // Controls the Audio & Video tab in Settings |
|
100 |
+var EnableAppearanceSettings = (getDbItem("EnableAppearanceSettings", "1") == "1"); // Controls the Appearance tab in Settings |
|
101 |
+var EnableChangeUserPasswordSettings = (getDbItem("EnableChangeUserPasswordSettings", "1") == "1"); // Controls the 'Change Password' tab in Settings |
|
102 |
+var EnableChangeUserEmailSettings = (getDbItem("EnableChangeUserEmailSettings", "1") == "1"); // Controls the 'Change Email' tab in Settings |
|
103 |
+var EnableCloseUserAccount = (getDbItem("EnableCloseUserAccount", "1") == "1"); // Controls the 'Close Account' tab in Settings |
|
104 |
+var EnableAlphanumericDial = (getDbItem("EnableAlphanumericDial", "1") == "1"); // Allows calling /[^\da-zA-Z\*\#\+]/g default is /[^\d\*\#\+]/g |
|
105 |
+var EnableVideoCalling = (getDbItem("EnableVideoCalling", "1") == "1"); // Enables Video during a call |
|
106 |
+var winVideoConf = null; |
|
107 |
+var winVideoConfCheck = 0; |
|
108 |
+ |
|
109 |
+// System variables |
|
110 |
+// ================ |
|
111 |
+var localDB = window.localStorage; |
|
112 |
+var userAgent = null; |
|
113 |
+var voicemailSubs = null; |
|
114 |
+var BlfSubs = []; |
|
115 |
+var CanvasCollection = []; |
|
116 |
+var Buddies = []; |
|
117 |
+var isReRegister = false; |
|
118 |
+var dhtmlxPopup = null; |
|
119 |
+var selectedBuddy = null; |
|
120 |
+var selectedLine = null; |
|
121 |
+var alertObj = null; |
|
122 |
+var confirmObj = null; |
|
123 |
+var promptObj = null; |
|
124 |
+var windowsCollection = null; |
|
125 |
+var messagingCollection = null; |
|
126 |
+var HasVideoDevice = false; |
|
127 |
+var HasAudioDevice = false; |
|
128 |
+var HasSpeakerDevice = false; |
|
129 |
+var AudioinputDevices = []; |
|
130 |
+var VideoinputDevices = []; |
|
131 |
+var SpeakerDevices = []; |
|
132 |
+var Lines = []; |
|
133 |
+var lang = {}; |
|
134 |
+var audioBlobs = {}; |
|
135 |
+var newLineNumber = 0; |
|
136 |
+var videoAudioCheck = 0; |
|
137 |
+var RCLoginCheck = 0; |
|
138 |
+var decSipPass = ''; |
|
139 |
+var currentChatPrivKey = ''; |
|
140 |
+var sendFileCheck = 0; |
|
141 |
+var upFileName = ''; |
|
142 |
+var sendFileChatErr = ''; |
|
143 |
+var pubKeyCheck = 0; |
|
144 |
+var splitMessage = {}; |
|
145 |
+ |
|
146 |
+// Utilities |
|
147 |
+// ========= |
|
148 |
+function uID(){ |
|
149 |
+ return Date.now()+Math.floor(Math.random()*10000).toString(16).toUpperCase(); |
|
150 |
+} |
|
151 |
+function utcDateNow(){ |
|
152 |
+ return moment().utc().format("YYYY-MM-DD HH:mm:ss UTC"); |
|
153 |
+} |
|
154 |
+function getDbItem(itemIndex, defaultValue){ |
|
155 |
+ var localDB = window.localStorage; |
|
156 |
+ if(localDB.getItem(itemIndex) != null) return localDB.getItem(itemIndex); |
|
157 |
+ return defaultValue; |
|
158 |
+} |
|
159 |
+function getAudioSrcID(){ |
|
160 |
+ var id = localDB.getItem("AudioSrcId"); |
|
161 |
+ return (id != null)? id : "default"; |
|
162 |
+} |
|
163 |
+function getAudioOutputID(){ |
|
164 |
+ var id = localDB.getItem("AudioOutputId"); |
|
165 |
+ return (id != null)? id : "default"; |
|
166 |
+} |
|
167 |
+function getVideoSrcID(){ |
|
168 |
+ var id = localDB.getItem("VideoSrcId"); |
|
169 |
+ return (id != null)? id : "default"; |
|
170 |
+} |
|
171 |
+function getRingerOutputID(){ |
|
172 |
+ var id = localDB.getItem("RingOutputId"); |
|
173 |
+ return (id != null)? id : "default"; |
|
174 |
+} |
|
175 |
+function formatDuration(seconds){ |
|
176 |
+ var sec = Math.floor(parseFloat(seconds)); |
|
177 |
+ if(sec < 0){ |
|
178 |
+ return sec; |
|
179 |
+ } |
|
180 |
+ else if(sec >= 0 && sec < 60){ |
|
181 |
+ return sec + " " + ((sec != 1) ? lang.seconds_plural : lang.second_single); |
|
182 |
+ } |
|
183 |
+ else if(sec >= 60 && sec < 60 * 60){ // greater then a minute and less then an hour |
|
184 |
+ var duration = moment.duration(sec, 'seconds'); |
|
185 |
+ return duration.minutes() + " "+ ((duration.minutes() != 1) ? lang.minutes_plural: lang.minute_single) +" " + duration.seconds() +" "+ ((duration.seconds() != 1) ? lang.seconds_plural : lang.second_single); |
|
186 |
+ } |
|
187 |
+ else if(sec >= 60 * 60 && sec < 24 * 60 * 60){ // greater than an hour and less then a day |
|
188 |
+ var duration = moment.duration(sec, 'seconds'); |
|
189 |
+ return duration.hours() + " "+ ((duration.hours() != 1) ? lang.hours_plural : lang.hour_single) +" " + duration.minutes() + " "+ ((duration.minutes() != 1) ? lang.minutes_plural: lang.minute_single) +" " + duration.seconds() +" "+ ((duration.seconds() != 1) ? lang.seconds_plural : lang.second_single); |
|
190 |
+ } |
|
191 |
+ // Otherwise.. this is just too long |
|
192 |
+} |
|
193 |
+function formatShortDuration(seconds) { |
|
194 |
+ var sec = Math.floor(parseFloat(seconds)); |
|
195 |
+ if(sec < 0){ |
|
196 |
+ return sec; |
|
197 |
+ } |
|
198 |
+ else if(sec >= 0 && sec < 60){ |
|
199 |
+ return "00:"+ ((sec > 9)? sec : "0"+sec ); |
|
200 |
+ } |
|
201 |
+ else if(sec >= 60 && sec < 60 * 60){ // greater then a minute and less then an hour |
|
202 |
+ var duration = moment.duration(sec, 'seconds'); |
|
203 |
+ return ((duration.minutes() > 9)? duration.minutes() : "0"+duration.minutes()) + ":" + ((duration.seconds() > 9)? duration.seconds() : "0"+duration.seconds()); |
|
204 |
+ } |
|
205 |
+ else if(sec >= 60 * 60 && sec < 24 * 60 * 60){ // greater than an hour and less then a day |
|
206 |
+ var duration = moment.duration(sec, 'seconds'); |
|
207 |
+ return ((duration.hours() > 9)? duration.hours() : "0"+duration.hours()) + ":" + ((duration.minutes() > 9)? duration.minutes() : "0"+duration.minutes()) + ":" + ((duration.seconds() > 9)? duration.seconds() : "0"+duration.seconds()); |
|
208 |
+ } |
|
209 |
+ // Otherwise.. this is just too long |
|
210 |
+} |
|
211 |
+function formatBytes(bytes, decimals) { |
|
212 |
+ if (bytes === 0) return "0 "+ lang.bytes; |
|
213 |
+ var k = 1024; |
|
214 |
+ var dm = (decimals && decimals >= 0)? decimals : 2; |
|
215 |
+ var sizes = [lang.bytes, lang.kb, lang.mb, lang.gb, lang.tb, lang.pb, lang.eb, lang.zb, lang.yb]; |
|
216 |
+ var i = Math.floor(Math.log(bytes) / Math.log(k)); |
|
217 |
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; |
|
218 |
+} |
|
219 |
+function UserLocale(){ |
|
220 |
+ var language = window.navigator.userLanguage || window.navigator.language; // "en", "en-US", "fr", "fr-FR", "es-ES", etc. |
|
221 |
+ |
|
222 |
+ langtag = language.split('-'); |
|
223 |
+ if(langtag.length == 1){ |
|
224 |
+ return ""; |
|
225 |
+ } |
|
226 |
+ else if(langtag.length == 2) { |
|
227 |
+ return langtag[1].toLowerCase(); // en-US => us |
|
228 |
+ } |
|
229 |
+ else if(langtag.length >= 3) { |
|
230 |
+ return langtag[1].toLowerCase(); // en-US => us |
|
231 |
+ } |
|
232 |
+} |
|
233 |
+function GetAlternateLanguage() { |
|
234 |
+ var userLanguage = window.navigator.userLanguage || window.navigator.language; // "en", "en-US", "fr", "fr-FR", "es-ES", etc. |
|
235 |
+ |
|
236 |
+ if(Language != "auto") userLanguage = Language; |
|
237 |
+ userLanguage = userLanguage.toLowerCase(); |
|
238 |
+ if(userLanguage == "en" || userLanguage.indexOf("en-") == 0) return ""; // English is already loaded |
|
239 |
+ |
|
240 |
+ for(l = 0; l < availableLang.length; l++) { |
|
241 |
+ if(userLanguage.indexOf(availableLang[l].toLowerCase()) == 0) { |
|
242 |
+ console.log("Alternate Language detected: ", userLanguage); |
|
243 |
+ // Set up Moment with the same langugae settings |
|
244 |
+ moment.locale(userLanguage); |
|
245 |
+ return availableLang[l].toLowerCase(); |
|
246 |
+ } |
|
247 |
+ } |
|
248 |
+ return ""; |
|
249 |
+} |
|
250 |
+function getFilter(filter, keyword) { |
|
251 |
+ if(filter.indexOf(",", filter.indexOf(keyword +": ") + keyword.length + 2) != -1) { |
|
252 |
+ return filter.substring(filter.indexOf(keyword +": ") + keyword.length + 2, filter.indexOf(",", filter.indexOf(keyword +": ") + keyword.length + 2)); |
|
253 |
+ } |
|
254 |
+ else { |
|
255 |
+ return filter.substring(filter.indexOf(keyword +": ") + keyword.length + 2); |
|
256 |
+ } |
|
257 |
+} |
|
258 |
+function base64toBlob(base64Data, contentType) { |
|
259 |
+ if(base64Data.indexOf("," != -1)) base64Data = base64Data.split(",")[1]; // [data:image/png;base64] , [xxx...] |
|
260 |
+ var byteCharacters = atob(base64Data); |
|
261 |
+ var slicesCount = Math.ceil(byteCharacters.length / 1024); |
|
262 |
+ var byteArrays = new Array(slicesCount); |
|
263 |
+ for (var s = 0; s < slicesCount; ++s) { |
|
264 |
+ var begin = s * 1024; |
|
265 |
+ var end = Math.min(begin + 1024, byteCharacters.length); |
|
266 |
+ var bytes = new Array(end - begin); |
|
267 |
+ for (var offset = begin, i = 0; offset < end; ++i, ++offset) { |
|
268 |
+ bytes[i] = byteCharacters[offset].charCodeAt(0); |
|
269 |
+ } |
|
270 |
+ byteArrays[s] = new Uint8Array(bytes); |
|
271 |
+ } |
|
272 |
+ return new Blob(byteArrays, { type: contentType }); |
|
273 |
+} |
|
274 |
+function MakeDataArray(defaultValue, count) { |
|
275 |
+ var rtnArray = new Array(count); |
|
276 |
+ for(var i=0; i< rtnArray.length; i++) { |
|
277 |
+ rtnArray[i] = defaultValue; |
|
278 |
+ } |
|
279 |
+ return rtnArray; |
|
280 |
+} |
|
281 |
+// Save account configuration data to SQL database |
|
282 |
+function saveConfToSqldb() { |
|
283 |
+ |
|
284 |
+ wssServer = $("#Configure_Account_wssServer").val(); |
|
285 |
+ WebSocketPort = parseInt($("#Configure_Account_WebSocketPort").val()); |
|
286 |
+ ServerPath = $("#Configure_Account_ServerPath").val(); |
|
287 |
+ profileName = $("#Configure_Account_profileName").val(); |
|
288 |
+ SipUsername = $("#Configure_Account_SipUsername").val(); |
|
289 |
+ SipPassword = $("#Configure_Account_SipPassword").val(); |
|
290 |
+ |
|
291 |
+ var STUNServer = $("#Configure_Account_StunServer").val(); |
|
292 |
+ var AUDIOOutputId = $("#playbackSrc").val(); |
|
293 |
+ var VIDEOSrcId = $("#previewVideoSrc").val(); |
|
294 |
+ var VIDEOHeight = $("input[name=Settings_Quality]:checked").val(); |
|
295 |
+ var FRAMERate = parseInt($("input[name=Settings_FrameRate]:checked").val()); |
|
296 |
+ var ASPECTRatio = $("input[name=Settings_AspectRatio]:checked").val(); |
|
297 |
+ var VIDEOOrientation = $("input[name=Settings_Oriteation]:checked").val(); |
|
298 |
+ var AUDIOSrcId = $("#microphoneSrc").val(); |
|
299 |
+ var AUTOGainControl = ($("#Settings_AutoGainControl").is(':checked'))? "1" : "0"; |
|
300 |
+ var ECHOCancellation = ($("#Settings_EchoCancellation").is(':checked'))? "1" : "0"; |
|
301 |
+ var NOISESuppression = ($("#Settings_NoiseSuppression").is(':checked'))? "1" : "0"; |
|
302 |
+ var RINGOutputId = $("#ringDevice").val(); |
|
303 |
+ var VideoConfExtension = $("#Video_Conf_Extension").val(); |
|
304 |
+ var VideoConfWindowWidth = $("#Video_Conf_Window_Width").val(); |
|
305 |
+ var PROFILEpicture = (typeof getDbItem("profilePicture", "") === 'undefined') ? "" : getDbItem("profilePicture", ""); |
|
306 |
+ var NOTIFYCheck = ($("#Settings_Notifications").is(":checked"))? 1 : 0; |
|
307 |
+ var EMAILIntegration = ($("#emailIntegration").is(":checked"))? 1 : 0; |
|
308 |
+ var RCDomain = $("#RoundcubeDomain").val(); |
|
309 |
+ var RCbasicauthuser = $("#rcBasicAuthUser").val(); |
|
310 |
+ var RCbasicauthpass = $("#rcBasicAuthPass").val(); |
|
311 |
+ var RCuser = $("#RoundcubeUser").val(); |
|
312 |
+ var RCpassword = $("#RoundcubePass").val(); |
|
313 |
+ |
|
314 |
+ if (userName != '') { |
|
315 |
+ |
|
316 |
+ if (wssServer != '' && WebSocketPort != '' && ServerPath != '' && SipUsername != '' && SipPassword != '') { |
|
317 |
+ |
|
318 |
+ $.ajax({ |
|
319 |
+ type: "POST", |
|
320 |
+ url: "save-update-settings.php", |
|
321 |
+ dataType: "JSON", |
|
322 |
+ data: { |
|
323 |
+ username: userName, |
|
324 |
+ wss_server: wssServer, |
|
325 |
+ web_socket_port: WebSocketPort, |
|
326 |
+ server_path: ServerPath, |
|
327 |
+ profile_name: profileName, |
|
328 |
+ sip_username: SipUsername, |
|
329 |
+ sip_password: SipPassword, |
|
330 |
+ stun_server: STUNServer, |
|
331 |
+ audio_output_id: AUDIOOutputId, |
|
332 |
+ video_src_id: VIDEOSrcId, |
|
333 |
+ video_height: VIDEOHeight, |
|
334 |
+ frame_rate: FRAMERate, |
|
335 |
+ aspect_ratio: ASPECTRatio, |
|
336 |
+ video_orientation: VIDEOOrientation, |
|
337 |
+ audio_src_id: AUDIOSrcId, |
|
338 |
+ auto_gain_control: AUTOGainControl, |
|
339 |
+ echo_cancellation: ECHOCancellation, |
|
340 |
+ noise_suppression: NOISESuppression, |
|
341 |
+ ring_output_id: RINGOutputId, |
|
342 |
+ video_conf_extension: VideoConfExtension, |
|
343 |
+ video_conf_window_width: VideoConfWindowWidth, |
|
344 |
+ profile_picture: PROFILEpicture, |
|
345 |
+ notifications: NOTIFYCheck, |
|
346 |
+ use_roundcube: EMAILIntegration, |
|
347 |
+ rcdomain: RCDomain, |
|
348 |
+ rcbasicauthuser: RCbasicauthuser, |
|
349 |
+ rcbasicauthpass: RCbasicauthpass, |
|
350 |
+ rcuser: RCuser, |
|
351 |
+ rcpassword: RCpassword, |
|
352 |
+ s_ajax_call: validateSToken |
|
353 |
+ }, |
|
354 |
+ success: function(response) { |
|
355 |
+ window.location.reload(); |
|
356 |
+ }, |
|
357 |
+ error: function(response) { |
|
358 |
+ alert("An error occurred while attempting to save the account configuration data!"); |
|
359 |
+ } |
|
360 |
+ }); |
|
361 |
+ |
|
362 |
+ } else { alert("Fields: 'WebSocket Domain', 'WebSocket Port', 'WebSocket Path', 'SIP Username' and 'SIP Password' are required ! Please fill in all these fields !"); } |
|
363 |
+ |
|
364 |
+ } else { alert("An error occurred while attempting to save the data!"); } |
|
365 |
+} |
|
366 |
+// Get account configuration data from SQL database |
|
367 |
+function getConfFromSqldb() { |
|
368 |
+ |
|
369 |
+ $.ajax({ |
|
370 |
+ type: "POST", |
|
371 |
+ url: "get-settings.php", |
|
372 |
+ dataType: "JSON", |
|
373 |
+ data: { |
|
374 |
+ username: userName, |
|
375 |
+ s_ajax_call: validateSToken |
|
376 |
+ }, |
|
377 |
+ success: function(datafromdb) { |
|
378 |
+ |
|
379 |
+ // Get configuration data from SQL database |
|
380 |
+ if (datafromdb.wss_server == null || datafromdb.web_socket_port == null || datafromdb.server_path == null || |
|
381 |
+ datafromdb.sip_username == null || datafromdb.sip_password == null) { |
|
382 |
+ |
|
383 |
+ ConfigureExtensionWindow(); |
|
384 |
+ |
|
385 |
+ } else { |
|
386 |
+ |
|
387 |
+ if (!localStorage.getItem('firstReLoad')) { |
|
388 |
+ localStorage['firstReLoad'] = true; |
|
389 |
+ window.setTimeout(function() { window.location.reload(); }, 200); |
|
390 |
+ } |
|
391 |
+ |
|
392 |
+ if (datafromdb.stun_server == null || typeof datafromdb.stun_server == 'undefined') { |
|
393 |
+ var stunData = ''; |
|
394 |
+ } else { var stunData = datafromdb.stun_server; } |
|
395 |
+ |
|
396 |
+ localDB.setItem("profileUserID", uID()); |
|
397 |
+ localDB.setItem("userrole", datafromdb.userrole); |
|
398 |
+ localDB.setItem("wssServer", datafromdb.wss_server); |
|
399 |
+ localDB.setItem("WebSocketPort", datafromdb.web_socket_port); |
|
400 |
+ localDB.setItem("ServerPath", datafromdb.server_path); |
|
401 |
+ localDB.setItem("profileUser", datafromdb.sip_username); |
|
402 |
+ localDB.setItem("profileName", datafromdb.profile_name); |
|
403 |
+ localDB.setItem("SipUsername", datafromdb.sip_username); |
|
404 |
+ localDB.setItem("SipPassword", datafromdb.sip_password); |
|
405 |
+ localDB.setItem("StunServer", stunData); |
|
406 |
+ localDB.setItem("AudioOutputId", datafromdb.audio_output_id); |
|
407 |
+ localDB.setItem("VideoSrcId", datafromdb.video_src_id); |
|
408 |
+ localDB.setItem("VideoHeight", datafromdb.video_height); |
|
409 |
+ localDB.setItem("FrameRate", datafromdb.frame_rate); |
|
410 |
+ localDB.setItem("AspectRatio", datafromdb.aspect_ratio); |
|
411 |
+ localDB.setItem("VideoOrientation", datafromdb.video_orientation); |
|
412 |
+ localDB.setItem("AudioSrcId", datafromdb.audio_src_id); |
|
413 |
+ localDB.setItem("AutoGainControl", datafromdb.auto_gain_control); |
|
414 |
+ localDB.setItem("EchoCancellation", datafromdb.echo_cancellation); |
|
415 |
+ localDB.setItem("NoiseSuppression", datafromdb.noise_suppression); |
|
416 |
+ localDB.setItem("RingOutputId", datafromdb.ring_output_id); |
|
417 |
+ localDB.setItem("VidConfExtension", datafromdb.video_conf_extension); |
|
418 |
+ localDB.setItem("VidConfWindowWidth", datafromdb.video_conf_window_width); |
|
419 |
+ localDB.setItem("profilePicture", datafromdb.profile_picture); |
|
420 |
+ localDB.setItem("Notifications", datafromdb.notifications); |
|
421 |
+ localDB.setItem("useRoundcube", datafromdb.use_roundcube); |
|
422 |
+ localDB.setItem("rcDomain", (datafromdb.rcdomain != '' && datafromdb.rcdomain != null && typeof datafromdb.rcdomain != 'undefined')? datafromdb.rcdomain : ""); |
|
423 |
+ localDB.setItem("rcBasicAuthUser", datafromdb.rcbasicauthuser); |
|
424 |
+ localDB.setItem("rcBasicAuthPass", datafromdb.rcbasicauthpass); |
|
425 |
+ localDB.setItem("RoundcubeUser", datafromdb.rcuser); |
|
426 |
+ localDB.setItem("RoundcubePass", datafromdb.rcpassword); |
|
427 |
+ |
|
428 |
+ Register(); |
|
429 |
+ } |
|
430 |
+ }, |
|
431 |
+ error: function(datafromdb) { |
|
432 |
+ alert("An error occurred while attempting to retrieve account configuration data from the database!"); |
|
433 |
+ } |
|
434 |
+ }); |
|
435 |
+} |
|
436 |
+ |
|
437 |
+// Save contact data to SQL database |
|
438 |
+function saveContactToSQLDB(newPerson) { |
|
439 |
+ |
|
440 |
+ if (newPerson.length != 0) { |
|
441 |
+ $.ajax({ |
|
442 |
+ type: "POST", |
|
443 |
+ url: "save-contact.php", |
|
444 |
+ dataType: "JSON", |
|
445 |
+ data: { |
|
446 |
+ username: userName, |
|
447 |
+ contact_name: newPerson[0], |
|
448 |
+ contact_desc: newPerson[1], |
|
449 |
+ extension_number: newPerson[2], |
|
450 |
+ contact_mobile: newPerson[3], |
|
451 |
+ contact_num1: newPerson[4], |
|
452 |
+ contact_num2: newPerson[5], |
|
453 |
+ contact_email: newPerson[6], |
|
454 |
+ s_ajax_call: validateSToken |
|
455 |
+ }, |
|
456 |
+ success: function(response) { |
|
457 |
+ if (response.result != 'success') { alert(response.result); } |
|
458 |
+ }, |
|
459 |
+ error: function(response) { |
|
460 |
+ alert("An error occurred while attempting to save the contact to the database!"); |
|
461 |
+ } |
|
462 |
+ }); |
|
463 |
+ } else { alert("An error occurred while attempting to save the data!"); } |
|
464 |
+} |
|
465 |
+ |
|
466 |
+// Update contact data in SQL database |
|
467 |
+function updateContactToSQLDB(newPerson) { |
|
468 |
+ |
|
469 |
+ if (newPerson.length != 0) { |
|
470 |
+ if (newPerson[7] != '' && newPerson[7] != null && typeof newPerson[7] != 'undefined') { |
|
471 |
+ $.ajax({ |
|
472 |
+ type: "POST", |
|
473 |
+ url: "update-contact.php", |
|
474 |
+ dataType: "JSON", |
|
475 |
+ data: { |
|
476 |
+ contact_name: newPerson[0], |
|
477 |
+ contact_desc: newPerson[1], |
|
478 |
+ extension_number: newPerson[2], |
|
479 |
+ contact_mobile: newPerson[3], |
|
480 |
+ contact_num1: newPerson[4], |
|
481 |
+ contact_num2: newPerson[5], |
|
482 |
+ contact_email: newPerson[6], |
|
483 |
+ contactDBID: newPerson[7], |
|
484 |
+ s_ajax_call: validateSToken |
|
485 |
+ }, |
|
486 |
+ success: function(response) { |
|
487 |
+ if (response.result != 'success') { alert(response.result); } |
|
488 |
+ }, |
|
489 |
+ error: function(response) { |
|
490 |
+ alert("An error occurred while attempting to save the data!"); |
|
491 |
+ } |
|
492 |
+ }); |
|
493 |
+ } else { alert("Error while attempting to retrieve contact data from the database!"); } |
|
494 |
+ } else { alert("An error occurred while attempting to save the data!"); } |
|
495 |
+} |
|
496 |
+// Save contact picture data to SQL database |
|
497 |
+function saveContactPicToSQLDB(newPic) { |
|
498 |
+ |
|
499 |
+ if (newPic.length != 0) { |
|
500 |
+ $.ajax({ |
|
501 |
+ type: "POST", |
|
502 |
+ url: "save-update-contact-picture.php", |
|
503 |
+ dataType: "JSON", |
|
504 |
+ data: { |
|
505 |
+ username: userName, |
|
506 |
+ contact_name: newPic[0], |
|
507 |
+ profile_picture_c: newPic[1], |
|
508 |
+ s_ajax_call: validateSToken |
|
509 |
+ }, |
|
510 |
+ success: function(response) { |
|
511 |
+ }, |
|
512 |
+ error: function(response) { |
|
513 |
+ alert("An error occurred while attempting to save contact picture!"); |
|
514 |
+ } |
|
515 |
+ }); |
|
516 |
+ } else { alert("An error occurred while attempting to save contact picture!"); } |
|
517 |
+} |
|
518 |
+// Get contact data from SQL database |
|
519 |
+function getContactsFromSQLDB() { |
|
520 |
+ |
|
521 |
+ $.ajax({ |
|
522 |
+ type: "POST", |
|
523 |
+ url: "get-contacts.php", |
|
524 |
+ dataType: "JSON", |
|
525 |
+ data: { |
|
526 |
+ username: userName, |
|
527 |
+ s_ajax_call: validateSToken |
|
528 |
+ }, |
|
529 |
+ success: function(contactsfromdb) { |
|
530 |
+ |
|
531 |
+ // Get contacts from SQL database and save them to localDB |
|
532 |
+ var jsonCon = InitUserBuddies(); |
|
533 |
+ |
|
534 |
+ $.each(contactsfromdb.contactsinfo, function(ind, contactrow) { |
|
535 |
+ var id = uID(); |
|
536 |
+ var dateNow = utcDateNow(); |
|
537 |
+ |
|
538 |
+ if (contactsfromdb.contactsinfo[ind].extension_number == '' || contactsfromdb.contactsinfo[ind].extension_number == null) { |
|
539 |
+ |
|
540 |
+ jsonCon.DataCollection.push( |
|
541 |
+ { |
|
542 |
+ Type: "contact", |
|
543 |
+ LastActivity: dateNow, |
|
544 |
+ ExtensionNumber: "", |
|
545 |
+ MobileNumber: contactsfromdb.contactsinfo[ind].contact_mobile, |
|
546 |
+ ContactNumber1: contactsfromdb.contactsinfo[ind].contact_num1, |
|
547 |
+ ContactNumber2: contactsfromdb.contactsinfo[ind].contact_num2, |
|
548 |
+ uID: null, |
|
549 |
+ cID: id, |
|
550 |
+ gID: null, |
|
551 |
+ DisplayName: contactsfromdb.contactsinfo[ind].contact_name, |
|
552 |
+ Position: "", |
|
553 |
+ Description: contactsfromdb.contactsinfo[ind].contact_desc, |
|
554 |
+ Email: contactsfromdb.contactsinfo[ind].contact_email, |
|
555 |
+ MemberCount: 0 |
|
556 |
+ } |
|
557 |
+ ); |
|
558 |
+ |
|
559 |
+ if (contactsfromdb.contactsinfo[ind].profile_picture_c != '' && contactsfromdb.contactsinfo[ind].profile_picture_c != null) { |
|
560 |
+ localDB.setItem("img-"+id+"-contact", contactsfromdb.contactsinfo[ind].profile_picture_c); |
|
561 |
+ } |
|
562 |
+ |
|
563 |
+ var buddyObj = new Buddy("contact", id, contactsfromdb.contactsinfo[ind].contact_name, "", contactsfromdb.contactsinfo[ind].contact_mobile, contactsfromdb.contactsinfo[ind].contact_num1, contactsfromdb.contactsinfo[ind].contact_num2, dateNow, contactsfromdb.contactsinfo[ind].contact_desc, contactsfromdb.contactsinfo[ind].contact_email); |
|
564 |
+ AddBuddy(buddyObj, true, false, false); |
|
565 |
+ |
|
566 |
+ } else { |
|
567 |
+ |
|
568 |
+ jsonCon.DataCollection.push( |
|
569 |
+ { |
|
570 |
+ Type: "extension", |
|
571 |
+ LastActivity: dateNow, |
|
572 |
+ ExtensionNumber: contactsfromdb.contactsinfo[ind].extension_number, |
|
573 |
+ MobileNumber: contactsfromdb.contactsinfo[ind].contact_mobile, |
|
574 |
+ ContactNumber1: contactsfromdb.contactsinfo[ind].contact_num1, |
|
575 |
+ ContactNumber2: contactsfromdb.contactsinfo[ind].contact_num2, |
|
576 |
+ uID: id, |
|
577 |
+ cID: null, |
|
578 |
+ gID: null, |
|
579 |
+ DisplayName: contactsfromdb.contactsinfo[ind].contact_name, |
|
580 |
+ Position: contactsfromdb.contactsinfo[ind].contact_desc, |
|
581 |
+ Description: "", |
|
582 |
+ Email: contactsfromdb.contactsinfo[ind].contact_email, |
|
583 |
+ MemberCount: 0 |
|
584 |
+ } |
|
585 |
+ ); |
|
586 |
+ |
|
587 |
+ if (contactsfromdb.contactsinfo[ind].profile_picture_c != '' && contactsfromdb.contactsinfo[ind].profile_picture_c != null) { |
|
588 |
+ localDB.setItem("img-"+id+"-extension", contactsfromdb.contactsinfo[ind].profile_picture_c); |
|
589 |
+ } |
|
590 |
+ |
|
591 |
+ var buddyObj = new Buddy("extension", id, contactsfromdb.contactsinfo[ind].contact_name, contactsfromdb.contactsinfo[ind].extension_number, contactsfromdb.contactsinfo[ind].contact_mobile, contactsfromdb.contactsinfo[ind].contact_num1, contactsfromdb.contactsinfo[ind].contact_num2, dateNow, contactsfromdb.contactsinfo[ind].contact_desc, contactsfromdb.contactsinfo[ind].contact_email); |
|
592 |
+ AddBuddy(buddyObj, true, false, true); |
|
593 |
+ } |
|
594 |
+ }); |
|
595 |
+ |
|
596 |
+ jsonCon.TotalRows = jsonCon.DataCollection.length; |
|
597 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(jsonCon)); |
|
598 |
+ |
|
599 |
+ UpdateUI(); |
|
600 |
+ PopulateBuddyList(); |
|
601 |
+ |
|
602 |
+ }, |
|
603 |
+ error: function(contactsfromdb) { |
|
604 |
+ alert("An error occurred while attempting to retrieve contacts data from the database!"); |
|
605 |
+ } |
|
606 |
+ }); |
|
607 |
+} |
|
608 |
+ |
|
609 |
+// Get external users data from SQL database |
|
610 |
+function getExternalUserConfFromSqldb() { |
|
611 |
+ |
|
612 |
+ $.ajax({ |
|
613 |
+ type: "POST", |
|
614 |
+ url: "get-external-users-conf.php", |
|
615 |
+ dataType: "JSON", |
|
616 |
+ data: { |
|
617 |
+ username: userName, |
|
618 |
+ s_ajax_call: validateSToken |
|
619 |
+ }, |
|
620 |
+ success: function(extdatafromdb) { |
|
621 |
+ |
|
622 |
+ var extdatafromdbstr = JSON.stringify(extdatafromdb); |
|
623 |
+ |
|
624 |
+ if (extdatafromdbstr.length > 0) { |
|
625 |
+ |
|
626 |
+ localDB.setItem("externalUserConfElem", extdatafromdb.length); |
|
627 |
+ |
|
628 |
+ for (var t = 0; t < extdatafromdb.length; t++) { |
|
629 |
+ localDB.setItem("extUserExtension-"+t, extdatafromdb[t]['exten_for_external']); |
|
630 |
+ localDB.setItem("extUserExtensionPass-"+t, extdatafromdb[t]['exten_for_ext_pass']); |
|
631 |
+ localDB.setItem("confAccessLink-"+t, extdatafromdb[t]['conf_access_link']); |
|
632 |
+ } |
|
633 |
+ } |
|
634 |
+ }, |
|
635 |
+ error: function(extdatafromdb) { |
|
636 |
+ alert("An error occurred while attempting to retrieve external users configuration data from the database!"); |
|
637 |
+ } |
|
638 |
+ }); |
|
639 |
+} |
|
640 |
+ |
|
641 |
+// Check if there are any links for external access associated with the current username |
|
642 |
+function checkExternalLinks() { |
|
643 |
+ |
|
644 |
+ if (confirm("Links that can allow external users to access the video conferences are stored in the database. If you don\'t need them anymore, it\'s recommended to remove them in order to prevent unwanted access to your conferences. Press OK to remove all the links for external access associated with your username from the database and then exit Roundpin, or press Cancel to leave the links in the database and just exit.")) { |
|
645 |
+ |
|
646 |
+ $.ajax({ |
|
647 |
+ type: "POST", |
|
648 |
+ url: "remove-links-for-external-access.php", |
|
649 |
+ dataType: "JSON", |
|
650 |
+ data: { |
|
651 |
+ username: userName, |
|
652 |
+ s_ajax_call: validateSToken |
|
653 |
+ }, |
|
654 |
+ success: function(response) { |
|
655 |
+ alert("All the links for external access to conferences associated with your username have been successfully removed from the database!"); |
|
656 |
+ |
|
657 |
+ Unregister(); |
|
658 |
+ console.log("Signing Out ..."); |
|
659 |
+ localStorage.clear(); |
|
660 |
+ if (winVideoConf != null) { |
|
661 |
+ winVideoConf.close(); |
|
662 |
+ } |
|
663 |
+ window.open('https://' + window.location.host + '/logout.php', '_self'); |
|
664 |
+ }, |
|
665 |
+ error: function(response) { |
|
666 |
+ alert("An error occurred while trying to remove the data from the database!"); |
|
667 |
+ |
|
668 |
+ Unregister(); |
|
669 |
+ console.log("Signing Out ..."); |
|
670 |
+ localStorage.clear(); |
|
671 |
+ if (winVideoConf != null) { |
|
672 |
+ winVideoConf.close(); |
|
673 |
+ } |
|
674 |
+ window.open('https://' + window.location.host + '/logout.php', '_self'); |
|
675 |
+ } |
|
676 |
+ }); |
|
677 |
+ |
|
678 |
+ } else { |
|
679 |
+ Unregister(); |
|
680 |
+ console.log("Signing Out ..."); |
|
681 |
+ localStorage.clear(); |
|
682 |
+ if (winVideoConf != null) { |
|
683 |
+ winVideoConf.close(); |
|
684 |
+ } |
|
685 |
+ window.open('https://' + window.location.host + '/logout.php', '_self'); |
|
686 |
+ } |
|
687 |
+} |
|
688 |
+ |
|
689 |
+// Remove contact from SQL database |
|
690 |
+function deleteBuddyFromSqldb(buddyDisplayName) { |
|
691 |
+ |
|
692 |
+ $.ajax({ |
|
693 |
+ type: "POST", |
|
694 |
+ url: "remove-contact.php", |
|
695 |
+ dataType: "JSON", |
|
696 |
+ data: { |
|
697 |
+ username: userName, |
|
698 |
+ contact_name: buddyDisplayName, |
|
699 |
+ s_ajax_call: validateSToken |
|
700 |
+ }, |
|
701 |
+ success: function(delresult) { |
|
702 |
+ }, |
|
703 |
+ error: function(delresult) { |
|
704 |
+ alert("An error occurred while attempting to remove the contact from the database!"); |
|
705 |
+ } |
|
706 |
+ }); |
|
707 |
+} |
|
708 |
+ |
|
709 |
+// Save new Roundpin user password |
|
710 |
+function saveNewUserPassword() { |
|
711 |
+ |
|
712 |
+ var currentPassword = $("#Current_User_Password").val(); |
|
713 |
+ var newPassword = $("#New_User_Password").val(); |
|
714 |
+ var repeatPassword = $("#Repeat_New_User_Password").val(); |
|
715 |
+ |
|
716 |
+ if (currentPassword == '' || newPassword == '' || repeatPassword == '') { alert("Please fill in all the fields!"); return; } |
|
717 |
+ |
|
718 |
+ // Verify if the new password meets constraints |
|
719 |
+ if (/^((?=.*\d)(?=.*[a-z])(?=.*\W).{10,})$/.test(newPassword)) { |
|
720 |
+ |
|
721 |
+ if (repeatPassword == newPassword) { |
|
722 |
+ $.ajax({ |
|
723 |
+ type: "POST", |
|
724 |
+ url: "save-new-user-password.php", |
|
725 |
+ dataType: "JSON", |
|
726 |
+ data: { |
|
727 |
+ username: userName, |
|
728 |
+ current_password: currentPassword, |
|
729 |
+ new_password: newPassword, |
|
730 |
+ s_ajax_call: validateSToken |
|
731 |
+ }, |
|
732 |
+ success: function(passchangemessage) { |
|
733 |
+ alert(passchangemessage); |
|
734 |
+ }, |
|
735 |
+ error: function(passchangemessage) { |
|
736 |
+ alert("An error occurred while attempting to change the user password!"); |
|
737 |
+ } |
|
738 |
+ }); |
|
739 |
+ } else { alert("The passwords entered in the new password fields don't match!"); } |
|
740 |
+ |
|
741 |
+ } else { |
|
742 |
+ alert("The new password does not meet the requirements (to be at least 10 characters long, to contain at least one letter, at least one digit and at least one special character). Please choose a different password ! "); |
|
743 |
+ } |
|
744 |
+} |
|
745 |
+ |
|
746 |
+// Save new Roundpin user email |
|
747 |
+function saveNewUserEmail() { |
|
748 |
+ |
|
749 |
+ var currentEmail = $("#Current_User_Email").val(); |
|
750 |
+ var newEmail = $("#New_User_Email").val(); |
|
751 |
+ var repeatEmail = $("#Repeat_New_User_Email").val(); |
|
752 |
+ |
|
753 |
+ if (currentEmail == '' || newEmail == '' || repeatEmail == '') { alert("Please fill in all the fields!"); return; } |
|
754 |
+ |
|
755 |
+ // Verify if the new email is a valid email address |
|
756 |
+ if (/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(newEmail)) { |
|
757 |
+ |
|
758 |
+ if (repeatEmail == newEmail) { |
|
759 |
+ $.ajax({ |
|
760 |
+ type: "POST", |
|
761 |
+ url: "save-new-user-email.php", |
|
762 |
+ dataType: "JSON", |
|
763 |
+ data: { |
|
764 |
+ username: userName, |
|
765 |
+ current_email: currentEmail, |
|
766 |
+ new_email: newEmail, |
|
767 |
+ s_ajax_call: validateSToken |
|
768 |
+ }, |
|
769 |
+ success: function(emailchangemessage) { |
|
770 |
+ alert(emailchangemessage); |
|
771 |
+ }, |
|
772 |
+ error: function(emailchangemessage) { |
|
773 |
+ alert("An error occurred while attempting to change the user email address!"); |
|
774 |
+ } |
|
775 |
+ }); |
|
776 |
+ } else { alert("The email addresses entered in the new email fields don't match!"); } |
|
777 |
+ |
|
778 |
+ } else { |
|
779 |
+ alert("The new email address is not a valid email address. Please enter a valid email address!"); |
|
780 |
+ } |
|
781 |
+} |
|
782 |
+ |
|
783 |
+// Close Roundpin user account |
|
784 |
+function closeUserAccount() { |
|
785 |
+ |
|
786 |
+ closeVideoAudio(); |
|
787 |
+ |
|
788 |
+ ConfirmConfigExtWindow(lang.confirm_close_account, lang.close_roundpin_user_account, function() { |
|
789 |
+ |
|
790 |
+ $.ajax({ |
|
791 |
+ type: "POST", |
|
792 |
+ url: "close-user-account.php", |
|
793 |
+ dataType: "JSON", |
|
794 |
+ data: { |
|
795 |
+ username: userName, |
|
796 |
+ s_ajax_call: validateSToken |
|
797 |
+ }, |
|
798 |
+ success: function(closeaccountmessage) { |
|
799 |
+ alert(closeaccountmessage); |
|
800 |
+ SignOut(); |
|
801 |
+ }, |
|
802 |
+ error: function(closeaccountmessage) { |
|
803 |
+ alert("An error occurred while attempting to close your user account!"); |
|
804 |
+ } |
|
805 |
+ }); |
|
806 |
+ }); |
|
807 |
+} |
|
808 |
+ |
|
809 |
+// Launch video conference |
|
810 |
+function LaunchVideoConference() { |
|
811 |
+ if (winVideoConfCheck == 0) { |
|
812 |
+ winVideoConf = window.open('https://' + window.location.host + '/videoconference/index.php'); |
|
813 |
+ winVideoConfCheck = 1; |
|
814 |
+ } else { alert("The video conference has been launched. If you want to launch it again refresh the page, then click \"Launch Video Conference\"."); } |
|
815 |
+} |
|
816 |
+// Generate a new text chat key |
|
817 |
+function generateChatRSAKeys(currentSIPusername) { |
|
818 |
+ |
|
819 |
+ var crypto = new JSEncrypt({default_key_size: 1024}); |
|
820 |
+ crypto.getKey(); |
|
821 |
+ var currentChatPubKey = crypto.getPublicKey(); |
|
822 |
+ currentChatPrivKey = crypto.getPrivateKey(); |
|
823 |
+ |
|
824 |
+ $.ajax({ |
|
825 |
+ type: "POST", |
|
826 |
+ url: "save-text-chat-pub-key.php", |
|
827 |
+ dataType: "JSON", |
|
828 |
+ data: { |
|
829 |
+ currentextension: currentSIPusername, |
|
830 |
+ currentchatpubkey: currentChatPubKey, |
|
831 |
+ s_ajax_call: validateSToken |
|
832 |
+ }, |
|
833 |
+ success: function() { |
|
834 |
+ }, |
|
835 |
+ error: function() { |
|
836 |
+ alert("An error occurred while trying to save the new text chat public key!"); |
|
837 |
+ } |
|
838 |
+ }); |
|
839 |
+} |
|
840 |
+ |
|
841 |
+// Remove the 'uploads' directory used to temporarily store files received during text chat |
|
842 |
+function removeTextChatUploads(currentSIPUser) { |
|
843 |
+ $.ajax({ |
|
844 |
+ 'async': false, |
|
845 |
+ 'global': false, |
|
846 |
+ type: "POST", |
|
847 |
+ url: "text-chat-remove-uploaded-files.php", |
|
848 |
+ dataType: "JSON", |
|
849 |
+ data: { |
|
850 |
+ sipusername: currentSIPUser, |
|
851 |
+ s_ajax_call: validateSToken |
|
852 |
+ }, |
|
853 |
+ success: function(resresult) { |
|
854 |
+ if (resresult.note != 'success') { |
|
855 |
+ alert("An error occurred while trying to remove the text chat 'uploads' directory!"); |
|
856 |
+ } |
|
857 |
+ }, |
|
858 |
+ error: function(resresult) { |
|
859 |
+ alert("An error occurred while attempting to remove the text chat 'uploads' directory!"); |
|
860 |
+ } |
|
861 |
+ }); |
|
862 |
+} |
|
863 |
+ |
|
864 |
+// On page reload, close the video conference tab if it is opened |
|
865 |
+function closeVideoConfTab() { |
|
866 |
+ if (winVideoConf) { winVideoConf.close(); } |
|
867 |
+} |
|
868 |
+ |
|
869 |
+// Show Email window |
|
870 |
+function ShowEmailWindow() { |
|
871 |
+ |
|
872 |
+ if (getDbItem("useRoundcube", "") == 1) { |
|
873 |
+ |
|
874 |
+ $("#roundcubeFrame").remove(); |
|
875 |
+ $("#rightContent").show(); |
|
876 |
+ $(".streamSelected").each(function() { $(this).css("display", "none"); }); |
|
877 |
+ $("#rightContent").append('<iframe id="roundcubeFrame" name="displayFrame"></iframe>'); |
|
878 |
+ |
|
879 |
+ var rcDomain = ''; |
|
880 |
+ var rcBasicAuthUser = ''; |
|
881 |
+ var rcBasicAuthPass = ''; |
|
882 |
+ var rcUsername = ''; |
|
883 |
+ var rcPasswd = ''; |
|
884 |
+ |
|
885 |
+ $.ajax({ |
|
886 |
+ 'async': false, |
|
887 |
+ 'global': false, |
|
888 |
+ type: "POST", |
|
889 |
+ url: "get-email-info.php", |
|
890 |
+ dataType: "JSON", |
|
891 |
+ data: { |
|
892 |
+ username: userName, |
|
893 |
+ s_ajax_call: validateSToken |
|
894 |
+ }, |
|
895 |
+ success: function(datafromdb) { |
|
896 |
+ rcDomain = datafromdb.rcdomain; |
|
897 |
+ rcBasicAuthUser = encodeURIComponent(datafromdb.rcbasicauthuser); |
|
898 |
+ rcBasicAuthPass = encodeURIComponent(datafromdb.rcbasicauthpass); |
|
899 |
+ rcUsername = datafromdb.rcuser; |
|
900 |
+ rcPasswd = datafromdb.rcpassword; |
|
901 |
+ }, |
|
902 |
+ error: function(datafromdb) { |
|
903 |
+ alert("An error occurred while trying to retrieve data from the database!"); |
|
904 |
+ } |
|
905 |
+ }); |
|
906 |
+ |
|
907 |
+ if (rcBasicAuthUser != '' && rcBasicAuthPass != '') { |
|
908 |
+ var actionURL = "https://"+ rcBasicAuthUser +":"+ rcBasicAuthPass +"@"+ rcDomain +"/"; |
|
909 |
+ } else { var actionURL = "https://"+ rcDomain +"/"; } |
|
910 |
+ |
|
911 |
+ var form = '<form id="rcForm" method="POST" action="'+ actionURL +'" target="displayFrame">'; |
|
912 |
+ form += '<input type="hidden" name="_action" value="login" />'; |
|
913 |
+ form += '<input type="hidden" name="_task" value="login" />'; |
|
914 |
+ form += '<input type="hidden" name="_autologin" value="1" />'; |
|
915 |
+ form += '<input name="_user" value="'+ rcUsername +'" type="text" />'; |
|
916 |
+ form += '<input name="_pass" value="'+ rcPasswd +'" type="password" />'; |
|
917 |
+ form += '<input id="submitButton" type="submit" value="Login" />'; |
|
918 |
+ form += '</form>'; |
|
919 |
+ |
|
920 |
+ $("#roundcubeFrame").append(form); |
|
921 |
+ |
|
922 |
+ if (RCLoginCheck == 0) { |
|
923 |
+ $("#submitButton").click(); |
|
924 |
+ RCLoginCheck = 1; |
|
925 |
+ } else { $("#roundcubeFrame").attr("src", actionURL); } |
|
926 |
+ |
|
927 |
+ } else { alert("Email Integration is not enabled ! You can enable Roundcube email integration by clicking on the 'Settings' wheel in the user profile section from below > 'Settings' > 'Email Integration' > 'Enable Roundcube email integration'"); } |
|
928 |
+} |
|
929 |
+ |
|
930 |
+// Shrink the left panel |
|
931 |
+function CollapseLeftPanel() { |
|
932 |
+ if ($(window).width() >= 920) { |
|
933 |
+ if ($("#leftContent").hasClass("shrinkLeftContent")) { |
|
934 |
+ $("#leftContent").removeClass("shrinkLeftContent"); |
|
935 |
+ $("#rightContent").removeClass("widenRightContent"); |
|
936 |
+ $('#aboutImg').css("margin-right", "-3px"); |
|
937 |
+ } else { |
|
938 |
+ $("#leftContent").addClass("shrinkLeftContent"); |
|
939 |
+ $("#rightContent").addClass("widenRightContent"); |
|
940 |
+ $('#aboutImg').css("margin-right", "3px"); |
|
941 |
+ } |
|
942 |
+ } |
|
943 |
+} |
|
944 |
+ |
|
945 |
+// Show the 'About' window |
|
946 |
+function ShowAboutWindow() { |
|
947 |
+ |
|
948 |
+ $.jeegoopopup.close(); |
|
949 |
+ var aboutHtml = '<div>'; |
|
950 |
+ aboutHtml += '<div id="windowCtrls"><img id="minimizeImg" src="images/1_minimize.svg" title="Restore" /><img id="maximizeImg" src="images/2_maximize.svg" title="Maximize" /><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
951 |
+ aboutHtml += '<div class="UiWindowField scroller">'; |
|
952 |
+ aboutHtml += '<div><img id="AboutLogoImg" src="images/login-logo.svg"/></div>'; |
|
953 |
+ aboutHtml += '<div id="aboutPopup">'+lang.about_text+'</div>'; |
|
954 |
+ aboutHtml += '</div></div>'; |
|
955 |
+ |
|
956 |
+ $.jeegoopopup.open({ |
|
957 |
+ title: 'About Roundpin', |
|
958 |
+ html: aboutHtml, |
|
959 |
+ width: '640', |
|
960 |
+ height: '500', |
|
961 |
+ center: true, |
|
962 |
+ scrolling: 'no', |
|
963 |
+ skinClass: 'jg_popup_basic', |
|
964 |
+ overlay: true, |
|
965 |
+ opacity: 50, |
|
966 |
+ draggable: true, |
|
967 |
+ resizable: false, |
|
968 |
+ fadeIn: 0 |
|
969 |
+ }); |
|
970 |
+ |
|
971 |
+ $("#jg_popup_b").append('<button id="ok_button">'+ lang.ok +'</button>'); |
|
972 |
+ |
|
973 |
+ var maxWidth = $(window).width() - 12; |
|
974 |
+ var maxHeight = $(window).height() - 88; |
|
975 |
+ |
|
976 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
977 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
978 |
+ $.jeegoopopup.center(); |
|
979 |
+ $("#maximizeImg").hide(); |
|
980 |
+ $("#minimizeImg").hide(); |
|
981 |
+ } else { |
|
982 |
+ $.jeegoopopup.width(640).height(500); |
|
983 |
+ $.jeegoopopup.center(); |
|
984 |
+ $("#minimizeImg").hide(); |
|
985 |
+ $("#maximizeImg").show(); |
|
986 |
+ } |
|
987 |
+ |
|
988 |
+ $(window).resize(function() { |
|
989 |
+ maxWidth = $(window).width() - 12; |
|
990 |
+ maxHeight = $(window).height() - 88; |
|
991 |
+ |
|
992 |
+ $.jeegoopopup.center(); |
|
993 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
994 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
995 |
+ $.jeegoopopup.center(); |
|
996 |
+ $("#maximizeImg").hide(); |
|
997 |
+ $("#minimizeImg").hide(); |
|
998 |
+ } else { |
|
999 |
+ $.jeegoopopup.width(640).height(500); |
|
1000 |
+ $.jeegoopopup.center(); |
|
1001 |
+ $("#minimizeImg").hide(); |
|
1002 |
+ $("#maximizeImg").show(); |
|
1003 |
+ } |
|
1004 |
+ }); |
|
1005 |
+ |
|
1006 |
+ |
|
1007 |
+ $("#minimizeImg").click(function() { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); }); |
|
1008 |
+ $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); }); |
|
1009 |
+ |
|
1010 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
1011 |
+ $("#ok_button").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
1012 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
1013 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); |
|
1014 |
+} |
|
1015 |
+ |
|
1016 |
+// Show system notifications on incoming calls |
|
1017 |
+function incomingCallNote() { |
|
1018 |
+ var incomingCallNotify = new Notification(lang.incomming_call, { icon: "../images/notification-logo.svg", body: "New incoming call !!!" }); |
|
1019 |
+ incomingCallNotify.onclick = function (event) { |
|
1020 |
+ return; |
|
1021 |
+ }; |
|
1022 |
+ |
|
1023 |
+ if (document.hasFocus()) { |
|
1024 |
+ return; |
|
1025 |
+ } else { setTimeout(incomingCallNote, 8000); } |
|
1026 |
+} |
|
1027 |
+ |
|
1028 |
+// Change page title on incoming calls |
|
1029 |
+function changePageTitle() { |
|
1030 |
+ if ($(document).attr("title") == "Roundpin") { $(document).prop("title", "New call !!!"); } else { $(document).prop("title", "Roundpin"); } |
|
1031 |
+ if (document.hasFocus()) { |
|
1032 |
+ $(document).prop("title", "Roundpin"); |
|
1033 |
+ return; |
|
1034 |
+ } else { setTimeout(changePageTitle, 460); } |
|
1035 |
+} |
|
1036 |
+ |
|
1037 |
+// Window and Document Events |
|
1038 |
+// ========================== |
|
1039 |
+$(window).on("beforeunload", function() { |
|
1040 |
+ Unregister(); |
|
1041 |
+}); |
|
1042 |
+$(window).on("resize", function() { |
|
1043 |
+ UpdateUI(); |
|
1044 |
+}); |
|
1045 |
+ |
|
1046 |
+// User Interface |
|
1047 |
+// ============== |
|
1048 |
+function UpdateUI(){ |
|
1049 |
+ if($(window).outerWidth() < 920){ |
|
1050 |
+ // Narrow Layout |
|
1051 |
+ if(selectedBuddy == null & selectedLine == null) { |
|
1052 |
+ // Nobody Selected |
|
1053 |
+ $("#rightContent").hide(); |
|
1054 |
+ |
|
1055 |
+ $("#leftContent").css("width", "100%"); |
|
1056 |
+ $("#leftContent").show(); |
|
1057 |
+ } |
|
1058 |
+ else { |
|
1059 |
+ $("#rightContent").css("margin-left", "0px"); |
|
1060 |
+ $("#rightContent").show(); |
|
1061 |
+ |
|
1062 |
+ $("#leftContent").hide(); |
|
1063 |
+ |
|
1064 |
+ if(selectedBuddy != null) updateScroll(selectedBuddy.identity); |
|
1065 |
+ } |
|
1066 |
+ } |
|
1067 |
+ else { |
|
1068 |
+ // Wide Screen Layout |
|
1069 |
+ if(selectedBuddy == null & selectedLine == null) { |
|
1070 |
+ $("#leftContent").css("width", "320px"); |
|
1071 |
+ $("#rightContent").css("margin-left", "0px"); |
|
1072 |
+ $("#leftContent").show(); |
|
1073 |
+ $("#rightContent").hide(); |
|
1074 |
+ } |
|
1075 |
+ else{ |
|
1076 |
+ $("#leftContent").css("width", "320px"); |
|
1077 |
+ $("#rightContent").css("margin-left", "320px"); |
|
1078 |
+ $("#leftContent").show(); |
|
1079 |
+ $("#rightContent").show(); |
|
1080 |
+ |
|
1081 |
+ if(selectedBuddy != null) updateScroll(selectedBuddy.identity); |
|
1082 |
+ } |
|
1083 |
+ } |
|
1084 |
+ for(var l=0; l<Lines.length; l++){ |
|
1085 |
+ updateLineScroll(Lines[l].LineNumber); |
|
1086 |
+ } |
|
1087 |
+} |
|
1088 |
+ |
|
1089 |
+// UI Windows |
|
1090 |
+// ========== |
|
1091 |
+function AddSomeoneWindow(numberStr){ |
|
1092 |
+ |
|
1093 |
+ $("#userMenu").hide(); |
|
1094 |
+ $.jeegoopopup.close(); |
|
1095 |
+ |
|
1096 |
+ var html = "<div id='AddNewContact'>"; |
|
1097 |
+ |
|
1098 |
+ html += "<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>"; |
|
1099 |
+ |
|
1100 |
+ html += "<div class='UiWindowField scroller'>"; |
|
1101 |
+ |
|
1102 |
+ html += "<div class=UiText>"+ lang.display_name +":</div>"; |
|
1103 |
+ html += "<div><input id=AddSomeone_Name class=UiInputText type=text placeholder='"+ lang.eg_display_name +"'></div>"; |
|
1104 |
+ |
|
1105 |
+ html += "<div class=UiText>"+ lang.title_description +":</div>"; |
|
1106 |
+ html += "<div><input id=AddSomeone_Desc class=UiInputText type=text placeholder='"+ lang.eg_general_manager +"'></div>"; |
|
1107 |
+ |
|
1108 |
+ html += "<div class=UiText>"+ lang.internal_subscribe_extension +":</div>"; |
|
1109 |
+ if(numberStr && numberStr.length > 1 && numberStr.length < DidLength && numberStr.substring(0,1) != "*"){ |
|
1110 |
+ html += "<div><input id=AddSomeone_Exten class=UiInputText type=text value="+ numberStr +" placeholder='"+ lang.eg_internal_subscribe_extension +"'></div>"; |
|
1111 |
+ } |
|
1112 |
+ else{ |
|
1113 |
+ html += "<div><input id=AddSomeone_Exten class=UiInputText type=text placeholder='"+ lang.eg_internal_subscribe_extension +"'></div>"; |
|
1114 |
+ } |
|
1115 |
+ |
|
1116 |
+ html += "<div class=UiText>"+ lang.mobile_number +":</div>"; |
|
1117 |
+ html += "<div><input id=AddSomeone_Mobile class=UiInputText type=text placeholder='"+ lang.eg_mobile_number +"'></div>"; |
|
1118 |
+ |
|
1119 |
+ html += "<div class=UiText>"+ lang.contact_number_1 +":</div>"; |
|
1120 |
+ if(numberStr && numberStr.length > 1){ |
|
1121 |
+ html += "<div><input id=AddSomeone_Num1 class=UiInputText type=text value="+ numberStr +" placeholder='"+ lang.eg_contact_number_1 +"'></div>"; |
|
1122 |
+ } |
|
1123 |
+ else { |
|
1124 |
+ html += "<div><input id=AddSomeone_Num1 class=UiInputText type=text placeholder='"+ lang.eg_contact_number_1 +"'></div>"; |
|
1125 |
+ } |
|
1126 |
+ |
|
1127 |
+ html += "<div class=UiText>"+ lang.contact_number_2 +":</div>"; |
|
1128 |
+ html += "<div><input id=AddSomeone_Num2 class=UiInputText type=text placeholder='"+ lang.eg_contact_number_2 +"'></div>"; |
|
1129 |
+ |
|
1130 |
+ html += "<div class=UiText>"+ lang.email +":</div>"; |
|
1131 |
+ html += "<div><input id=AddSomeone_Email class=UiInputText type=text placeholder='"+ lang.eg_email +"'></div>"; |
|
1132 |
+ |
|
1133 |
+ html += "</div></div>" |
|
1134 |
+ |
|
1135 |
+ $.jeegoopopup.open({ |
|
1136 |
+ title: 'Add Contact', |
|
1137 |
+ html: html, |
|
1138 |
+ width: '640', |
|
1139 |
+ height: '500', |
|
1140 |
+ center: true, |
|
1141 |
+ scrolling: 'no', |
|
1142 |
+ skinClass: 'jg_popup_basic', |
|
1143 |
+ contentClass: 'addContactPopup', |
|
1144 |
+ overlay: true, |
|
1145 |
+ opacity: 50, |
|
1146 |
+ draggable: true, |
|
1147 |
+ resizable: false, |
|
1148 |
+ fadeIn: 0 |
|
1149 |
+ }); |
|
1150 |
+ |
|
1151 |
+ $("#jg_popup_b").append("<div id=bottomButtons><button id=save_button>Save</button><button id=cancel_button>Cancel</button></div>"); |
|
1152 |
+ |
|
1153 |
+ $("#save_button").click(function() { |
|
1154 |
+ |
|
1155 |
+ var currentASName = $("#AddSomeone_Name").val(); |
|
1156 |
+ |
|
1157 |
+ if (currentASName != null && currentASName.trim() !== '') { |
|
1158 |
+ |
|
1159 |
+ if (/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(currentASName)) { |
|
1160 |
+ |
|
1161 |
+ var currentDesc = $("#AddSomeone_Desc").val(); |
|
1162 |
+ if (currentDesc != null && currentDesc.trim() !== '') { |
|
1163 |
+ if (/^[A-Za-z0-9\s\-\.\'\"\[\]\(\)\{\}\_\!\?\~\@\%\^\&\*\+\>\<\;\:\=]+$/.test(currentDesc)) { var finCurrentDesc = currentDesc; } else { |
|
1164 |
+ var finCurrentDesc = ''; alert('The title/description that you entered is not valid!'); } |
|
1165 |
+ } else { var finCurrentDesc = ''; } |
|
1166 |
+ |
|
1167 |
+ var currentExtension = $("#AddSomeone_Exten").val(); |
|
1168 |
+ if (currentExtension != null && currentExtension.trim() !== '') { |
|
1169 |
+ if (/^[a-zA-Z0-9\*\#]+$/.test(currentExtension)) { var finCurrentExtension = currentExtension; } else { |
|
1170 |
+ var finCurrentExtension = ''; alert("The extension that you entered in the 'Extension (Internal)' field is not a valid extension!"); } |
|
1171 |
+ } else { var finCurrentExtension = ''; } |
|
1172 |
+ |
|
1173 |
+ var currentMobile = $("#AddSomeone_Mobile").val(); |
|
1174 |
+ if (currentMobile != null && currentMobile.trim() !== '') { |
|
1175 |
+ if (/^[0-9\s\+\#]+$/.test(currentMobile)) { var finCurrentMobile = currentMobile; } else { |
|
1176 |
+ var finCurrentMobile = ''; alert("The phone number that you entered in the 'Mobile Number' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); } |
|
1177 |
+ } else { var finCurrentMobile = ''; } |
|
1178 |
+ |
|
1179 |
+ var currentNum1 = $("#AddSomeone_Num1").val(); |
|
1180 |
+ if (currentNum1 != null && currentNum1.trim() !== '') { |
|
1181 |
+ if (/^[0-9\s\+\#]+$/.test(currentNum1)) { var finCurrentNum1 = currentNum1; } else { |
|
1182 |
+ var finCurrentNum1 = ''; alert("The phone number that you entered in the 'Contact Number 1' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); } |
|
1183 |
+ } else { var finCurrentNum1 = ''; } |
|
1184 |
+ |
|
1185 |
+ var currentNum2 = $("#AddSomeone_Num2").val(); |
|
1186 |
+ if (currentNum2 != null && currentNum2.trim() !== '') { |
|
1187 |
+ if (/^[0-9\s\+\#]+$/.test(currentNum2)) { var finCurrentNum2 = currentNum2; } else { |
|
1188 |
+ var finCurrentNum2 = ''; alert("The phone number that you entered in the 'Contact Number 2' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); } |
|
1189 |
+ } else { var finCurrentNum2 = ''; } |
|
1190 |
+ |
|
1191 |
+ var currentEmail = $("#AddSomeone_Email").val(); |
|
1192 |
+ if (currentEmail != null && currentEmail.trim() !== '') { |
|
1193 |
+ if (/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(currentEmail)) { var finCurrentEmail = currentEmail; } else { |
|
1194 |
+ var finCurrentEmail = ''; alert("The email that you entered is not a valid email address!"); } |
|
1195 |
+ } else { var finCurrentEmail = ''; } |
|
1196 |
+ |
|
1197 |
+ |
|
1198 |
+ // Add Contact / Extension |
|
1199 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
1200 |
+ if(json == null) json = InitUserBuddies(); |
|
1201 |
+ |
|
1202 |
+ if(finCurrentExtension == ''){ |
|
1203 |
+ // Add Regular Contact |
|
1204 |
+ var id = uID(); |
|
1205 |
+ var dateNow = utcDateNow(); |
|
1206 |
+ json.DataCollection.push( |
|
1207 |
+ { |
|
1208 |
+ Type: "contact", |
|
1209 |
+ LastActivity: dateNow, |
|
1210 |
+ ExtensionNumber: "", |
|
1211 |
+ MobileNumber: finCurrentMobile, |
|
1212 |
+ ContactNumber1: finCurrentNum1, |
|
1213 |
+ ContactNumber2: finCurrentNum2, |
|
1214 |
+ uID: null, |
|
1215 |
+ cID: id, |
|
1216 |
+ gID: null, |
|
1217 |
+ DisplayName: currentASName, |
|
1218 |
+ Position: "", |
|
1219 |
+ Description: finCurrentDesc, |
|
1220 |
+ Email: finCurrentEmail, |
|
1221 |
+ MemberCount: 0 |
|
1222 |
+ } |
|
1223 |
+ ); |
|
1224 |
+ var newPerson = []; |
|
1225 |
+ newPerson = [currentASName, finCurrentDesc, "", finCurrentMobile, finCurrentNum1, finCurrentNum2, finCurrentEmail]; |
|
1226 |
+ saveContactToSQLDB(newPerson); |
|
1227 |
+ |
|
1228 |
+ var buddyObj = new Buddy("contact", id, currentASName, "", finCurrentMobile, finCurrentNum1, finCurrentNum2, dateNow, finCurrentDesc, finCurrentEmail); |
|
1229 |
+ AddBuddy(buddyObj, false, false, false); |
|
1230 |
+ |
|
1231 |
+ } else { |
|
1232 |
+ // Add Extension |
|
1233 |
+ var id = uID(); |
|
1234 |
+ var dateNow = utcDateNow(); |
|
1235 |
+ json.DataCollection.push( |
|
1236 |
+ { |
|
1237 |
+ Type: "extension", |
|
1238 |
+ LastActivity: dateNow, |
|
1239 |
+ ExtensionNumber: finCurrentExtension, |
|
1240 |
+ MobileNumber: finCurrentMobile, |
|
1241 |
+ ContactNumber1: finCurrentNum1, |
|
1242 |
+ ContactNumber2: finCurrentNum2, |
|
1243 |
+ uID: id, |
|
1244 |
+ cID: null, |
|
1245 |
+ gID: null, |
|
1246 |
+ DisplayName: currentASName, |
|
1247 |
+ Position: finCurrentDesc, |
|
1248 |
+ Description: "", |
|
1249 |
+ Email: finCurrentEmail, |
|
1250 |
+ MemberCount: 0 |
|
1251 |
+ } |
|
1252 |
+ ); |
|
1253 |
+ |
|
1254 |
+ var newPerson = []; |
|
1255 |
+ |
|
1256 |
+ newPerson = [currentASName, finCurrentDesc, finCurrentExtension, finCurrentMobile, finCurrentNum1, finCurrentNum2, finCurrentEmail]; |
|
1257 |
+ saveContactToSQLDB(newPerson); |
|
1258 |
+ |
|
1259 |
+ var buddyObj = new Buddy("extension", id, currentASName, finCurrentExtension, finCurrentMobile, finCurrentNum1, finCurrentNum2, dateNow, finCurrentDesc, finCurrentEmail); |
|
1260 |
+ AddBuddy(buddyObj, false, false, true); |
|
1261 |
+ |
|
1262 |
+ } |
|
1263 |
+ // Update Size: |
|
1264 |
+ json.TotalRows = json.DataCollection.length; |
|
1265 |
+ |
|
1266 |
+ // Save To Local DB |
|
1267 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
1268 |
+ UpdateBuddyList(); |
|
1269 |
+ |
|
1270 |
+ $.jeegoopopup.close(); |
|
1271 |
+ $("#jg_popup_b").empty(); |
|
1272 |
+ |
|
1273 |
+ } else { alert('The display name that you entered is not a valid display name!'); } |
|
1274 |
+ |
|
1275 |
+ } else { alert("'Display Name' cannot be empty!"); } |
|
1276 |
+ |
|
1277 |
+ }); |
|
1278 |
+ |
|
1279 |
+ var maxWidth = $(window).width() - 12; |
|
1280 |
+ var maxHeight = $(window).height() - 110; |
|
1281 |
+ |
|
1282 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
1283 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
1284 |
+ $.jeegoopopup.center(); |
|
1285 |
+ $("#maximizeImg").hide(); |
|
1286 |
+ $("#minimizeImg").hide(); |
|
1287 |
+ } else { |
|
1288 |
+ $.jeegoopopup.width(640).height(500); |
|
1289 |
+ $.jeegoopopup.center(); |
|
1290 |
+ $("#minimizeImg").hide(); |
|
1291 |
+ $("#maximizeImg").show(); |
|
1292 |
+ } |
|
1293 |
+ |
|
1294 |
+ $(window).resize(function() { |
|
1295 |
+ maxWidth = $(window).width() - 16; |
|
1296 |
+ maxHeight = $(window).height() - 110; |
|
1297 |
+ $.jeegoopopup.center(); |
|
1298 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
1299 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
1300 |
+ $.jeegoopopup.center(); |
|
1301 |
+ $("#maximizeImg").hide(); |
|
1302 |
+ $("#minimizeImg").hide(); |
|
1303 |
+ } else { |
|
1304 |
+ $.jeegoopopup.width(640).height(500); |
|
1305 |
+ $.jeegoopopup.center(); |
|
1306 |
+ $("#minimizeImg").hide(); |
|
1307 |
+ $("#maximizeImg").show(); |
|
1308 |
+ } |
|
1309 |
+ }); |
|
1310 |
+ |
|
1311 |
+ $("#minimizeImg").click(function() { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); }); |
|
1312 |
+ $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); }); |
|
1313 |
+ |
|
1314 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
1315 |
+ $("#cancel_button").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
1316 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
1317 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); |
|
1318 |
+} |
|
1319 |
+ |
|
1320 |
+function CreateGroupWindow(){ |
|
1321 |
+} |
|
1322 |
+ |
|
1323 |
+function closeVideoAudio() { |
|
1324 |
+ |
|
1325 |
+ var localVideo = $("#local-video-preview").get(0); |
|
1326 |
+ try{ |
|
1327 |
+ var tracks = localVideo.srcObject.getTracks(); |
|
1328 |
+ tracks.forEach(function(track) { |
|
1329 |
+ track.stop(); |
|
1330 |
+ }); |
|
1331 |
+ localVideo.srcObject = null; |
|
1332 |
+ } |
|
1333 |
+ catch(e){} |
|
1334 |
+ |
|
1335 |
+ try{ |
|
1336 |
+ var tracks = window.SettingsMicrophoneStream.getTracks(); |
|
1337 |
+ tracks.forEach(function(track) { |
|
1338 |
+ track.stop(); |
|
1339 |
+ }); |
|
1340 |
+ } |
|
1341 |
+ catch(e){} |
|
1342 |
+ window.SettingsMicrophoneStream = null; |
|
1343 |
+ |
|
1344 |
+ try{ |
|
1345 |
+ var soundMeter = window.SettingsMicrophoneSoundMeter; |
|
1346 |
+ soundMeter.stop(); |
|
1347 |
+ } |
|
1348 |
+ catch(e){} |
|
1349 |
+ window.SettingsMicrophoneSoundMeter = null; |
|
1350 |
+ |
|
1351 |
+ try{ |
|
1352 |
+ window.SettingsOutputAudio.pause(); |
|
1353 |
+ } |
|
1354 |
+ catch(e){} |
|
1355 |
+ window.SettingsOutputAudio = null; |
|
1356 |
+ |
|
1357 |
+ try{ |
|
1358 |
+ var tracks = window.SettingsOutputStream.getTracks(); |
|
1359 |
+ tracks.forEach(function(track) { |
|
1360 |
+ track.stop(); |
|
1361 |
+ }); |
|
1362 |
+ } |
|
1363 |
+ catch(e){} |
|
1364 |
+ window.SettingsOutputStream = null; |
|
1365 |
+ |
|
1366 |
+ try{ |
|
1367 |
+ var soundMeter = window.SettingsOutputStreamMeter; |
|
1368 |
+ soundMeter.stop(); |
|
1369 |
+ } |
|
1370 |
+ catch(e){} |
|
1371 |
+ window.SettingsOutputStreamMeter = null; |
|
1372 |
+ |
|
1373 |
+ return true; |
|
1374 |
+} |
|
1375 |
+function ConfigureExtensionWindow() { |
|
1376 |
+ |
|
1377 |
+ $("#settingsCMenu").hide(); |
|
1378 |
+ $.jeegoopopup.close(); |
|
1379 |
+ |
|
1380 |
+ var configWindow = "<div id=\"mainConfWindow\">"; |
|
1381 |
+ configWindow += "<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>"; |
|
1382 |
+ configWindow += "<div id=\"mainRightConf\">"; |
|
1383 |
+ configWindow += "<div id=\"rightMainConfWindow\">"; |
|
1384 |
+ |
|
1385 |
+ configWindow += "<div id=\"AccountHtml\" class=\"settingsSubSection\" style=\"display:block;\">"; |
|
1386 |
+ configWindow += "<div class=UiText>"+ lang.asterisk_server_address +": *</div>"; |
|
1387 |
+ configWindow += "<div><input id=Configure_Account_wssServer class=UiInputText type=text placeholder='"+ lang.eg_asterisk_server_address +"' value='"+ getDbItem("wssServer", "") +"'></div>"; |
|
1388 |
+ configWindow += "<div class=UiText>"+ lang.websocket_port +": *</div>"; |
|
1389 |
+ configWindow += "<div><input id=Configure_Account_WebSocketPort class=UiInputText type=text placeholder='"+ lang.eg_websocket_port +"' value='"+ getDbItem("WebSocketPort", "") +"'></div>"; |
|
1390 |
+ configWindow += "<div class=UiText>"+ lang.websocket_path +": *</div>"; |
|
1391 |
+ configWindow += "<div><input id=Configure_Account_ServerPath class=UiInputText type=text placeholder='"+ lang.eg_websocket_path +"' value='"+ getDbItem("ServerPath", "") +"'></div>"; |
|
1392 |
+ configWindow += "<div class=UiText>"+ lang.display_name +": *</div>"; |
|
1393 |
+ |
|
1394 |
+ var escapedDisplayName = 'value="' + getDbItem("profileName", "").replace("'","\'") + '"'; |
|
1395 |
+ configWindow += "<div><input id=Configure_Account_profileName class=UiInputText type=text placeholder='"+ lang.eg_display_name +"' "+ escapedDisplayName +"></div>"; |
|
1396 |
+ configWindow += "<div class=UiText>"+ lang.sip_username +": *</div>"; |
|
1397 |
+ configWindow += "<div><input id=Configure_Account_SipUsername class=UiInputText type=text placeholder='"+ lang.eg_sip_username +"' value='"+ getDbItem("SipUsername", "") +"'></div>"; |
|
1398 |
+ configWindow += "<div class=UiText>"+ lang.sip_password +": *</div>"; |
|
1399 |
+ configWindow += "<div><input id=Configure_Account_SipPassword class=UiInputText type=password placeholder='"+ lang.eg_sip_password +"' value='"+ getDbItem("SipPassword", "") +"'></div>"; |
|
1400 |
+ configWindow += "<div class=UiText>"+ lang.stun_server +":</div>"; |
|
1401 |
+ configWindow += "<div><input id=Configure_Account_StunServer class=UiInputText type=text placeholder='Eg: 123.123.123.123:8443' value='"+ getDbItem("StunServer", "") +"'></div>"; |
|
1402 |
+ configWindow += "<p style=\"color:#363636;\">* Required field.</p><br><br></div>"; |
|
1403 |
+ |
|
1404 |
+ configWindow += "<div id=\"AudioVideoHtml\" class=\"settingsSubSection\" style=\"display:none;\">"; |
|
1405 |
+ configWindow += "<div class=UiText>"+ lang.speaker +":</div>"; |
|
1406 |
+ configWindow += "<div style=\"text-align:center\"><select id=playbackSrc style=\"width:100%\"></select></div>"; |
|
1407 |
+ configWindow += "<div class=Settings_VolumeOutput_Container><div id=Settings_SpeakerOutput class=Settings_VolumeOutput></div></div>"; |
|
1408 |
+ configWindow += "<div><button class=on_white id=preview_output_play><i class=\"fa fa-play\"></i></button><button class=on_white id=preview_output_pause><i class=\"fa fa-pause\"></i></button></div>"; |
|
1409 |
+ |
|
1410 |
+ configWindow += "<br><div class=UiText>"+ lang.ring_device +":</div>"; |
|
1411 |
+ configWindow += "<div style=\"text-align:center\"><select id=ringDevice style=\"width:100%\"></select></div>"; |
|
1412 |
+ configWindow += "<div class=Settings_VolumeOutput_Container><div id=Settings_RingerOutput class=Settings_VolumeOutput></div></div>"; |
|
1413 |
+ configWindow += "<div><button class=on_white id=preview_ringer_play><i class=\"fa fa-play\"></i></button></div>"; |
|
1414 |
+ |
|
1415 |
+ configWindow += "<br><div class=UiText>"+ lang.microphone +":</div>"; |
|
1416 |
+ configWindow += "<div style=\"text-align:center\"><select id=microphoneSrc style=\"width:100%\"></select></div>"; |
|
1417 |
+ configWindow += "<div class=Settings_VolumeOutput_Container><div id=Settings_MicrophoneOutput class=Settings_VolumeOutput></div></div>"; |
|
1418 |
+ configWindow += "<br><br><div><input type=checkbox id=Settings_AutoGainControl><label for=Settings_AutoGainControl> "+ lang.auto_gain_control +"<label></div>"; |
|
1419 |
+ configWindow += "<div><input type=checkbox id=Settings_EchoCancellation><label for=Settings_EchoCancellation> "+ lang.echo_cancellation +"<label></div>"; |
|
1420 |
+ configWindow += "<div><input type=checkbox id=Settings_NoiseSuppression><label for=Settings_NoiseSuppression> "+ lang.noise_suppression +"<label></div>"; |
|
1421 |
+ configWindow += "<br><div class=UiText>"+ lang.camera +":</div>"; |
|
1422 |
+ configWindow += "<div style=\"text-align:center\"><select id=previewVideoSrc style=\"width:100%\"></select></div>"; |
|
1423 |
+ configWindow += "<br><div class=UiText>"+ lang.frame_rate +":</div>" |
|
1424 |
+ configWindow += "<div class=pill-nav>"; |
|
1425 |
+ configWindow += "<input name=Settings_FrameRate id=r40 type=radio value=\"2\"><label class=radio_pill for=r40>2</label>"; |
|
1426 |
+ configWindow += "<input name=Settings_FrameRate id=r41 type=radio value=\"5\"><label class=radio_pill for=r41>5</label>"; |
|
1427 |
+ configWindow += "<input name=Settings_FrameRate id=r42 type=radio value=\"10\"><label class=radio_pill for=r42>10</label>"; |
|
1428 |
+ configWindow += "<input name=Settings_FrameRate id=r43 type=radio value=\"15\"><label class=radio_pill for=r43>15</label>"; |
|
1429 |
+ configWindow += "<input name=Settings_FrameRate id=r44 type=radio value=\"20\"><label class=radio_pill for=r44>20</label>"; |
|
1430 |
+ configWindow += "<input name=Settings_FrameRate id=r45 type=radio value=\"25\"><label class=radio_pill for=r45>25</label>"; |
|
1431 |
+ configWindow += "<input name=Settings_FrameRate id=r46 type=radio value=\"30\"><label class=radio_pill for=r46>30</label>"; |
|
1432 |
+ configWindow += "<input name=Settings_FrameRate id=r47 type=radio value=\"\"><label class=radio_pill for=r47><i class=\"fa fa-trash\"></i></label>"; |
|
1433 |
+ configWindow += "</div>"; |
|
1434 |
+ configWindow += "<br><br><div class=UiText>"+ lang.quality +":</div>"; |
|
1435 |
+ configWindow += "<div class=pill-nav>"; |
|
1436 |
+ configWindow += "<input name=Settings_Quality id=r30 type=radio value=\"160\"><label class=radio_pill for=r30><i class=\"fa fa-video-camera\" style=\"transform: scale(0.4)\"></i> HQVGA</label>"; |
|
1437 |
+ configWindow += "<input name=Settings_Quality id=r31 type=radio value=\"240\"><label class=radio_pill for=r31><i class=\"fa fa-video-camera\" style=\"transform: scale(0.6)\"></i> QVGA</label>"; |
|
1438 |
+ configWindow += "<input name=Settings_Quality id=r32 type=radio value=\"480\"><label class=radio_pill for=r32><i class=\"fa fa-video-camera\" style=\"transform: scale(0.8)\"></i> VGA</label>"; |
|
1439 |
+ configWindow += "<input name=Settings_Quality id=r33 type=radio value=\"720\"><label class=radio_pill for=r33><i class=\"fa fa-video-camera\" style=\"transform: scale(1)\"></i> HD</label>"; |
|
1440 |
+ configWindow += "<input name=Settings_Quality id=r34 type=radio value=\"\"><label class=radio_pill for=r34><i class=\"fa fa-trash\"></i></label>"; |
|
1441 |
+ configWindow += "</div>"; |
|
1442 |
+ configWindow += "<br><br><div class=UiText>"+ lang.image_orientation +":</div>"; |
|
1443 |
+ configWindow += "<div class=pill-nav>"; |
|
1444 |
+ configWindow += "<input name=Settings_Oriteation id=r20 type=radio value=\"rotateY(0deg)\"><label class=radio_pill for=r20><i class=\"fa fa-address-card\" style=\"transform: rotateY(0deg)\"></i> Normal</label>"; |
|
1445 |
+ configWindow += "<input name=Settings_Oriteation id=r21 type=radio value=\"rotateY(180deg)\"><label class=radio_pill for=r21><i class=\"fa fa-address-card\" style=\"transform: rotateY(180deg)\"></i> Mirror</label>"; |
|
1446 |
+ configWindow += "</div>"; |
|
1447 |
+ configWindow += "<br><br><div class=UiText>"+ lang.aspect_ratio +":</div>"; |
|
1448 |
+ configWindow += "<div class=pill-nav>"; |
|
1449 |
+ configWindow += "<input name=Settings_AspectRatio id=r10 type=radio value=\"1\"><label class=radio_pill for=r10><i class=\"fa fa-square-o\" style=\"transform: scaleX(1); margin-left: 7px; margin-right: 7px\"></i> 1:1</label>"; |
|
1450 |
+ configWindow += "<input name=Settings_AspectRatio id=r11 type=radio value=\"1.33\"><label class=radio_pill for=r11><i class=\"fa fa-square-o\" style=\"transform: scaleX(1.33); margin-left: 5px; margin-right: 5px;\"></i> 4:3</label>"; |
|
1451 |
+ configWindow += "<input name=Settings_AspectRatio id=r12 type=radio value=\"1.77\"><label class=radio_pill for=r12><i class=\"fa fa-square-o\" style=\"transform: scaleX(1.77); margin-right: 3px;\"></i> 16:9</label>"; |
|
1452 |
+ configWindow += "<input name=Settings_AspectRatio id=r13 type=radio value=\"\"><label class=radio_pill for=r13><i class=\"fa fa-trash\"></i></label>"; |
|
1453 |
+ configWindow += "</div>"; |
|
1454 |
+ configWindow += "<br><br><div class=UiText>"+ lang.preview +":</div>"; |
|
1455 |
+ configWindow += "<div style=\"text-align:center; margin-top:10px\"><video id=\"local-video-preview\" class=\"previewVideo\"></video></div>"; |
|
1456 |
+ configWindow += "<br><div class=UiText>"+ lang.video_conference_extension +":</div>"; |
|
1457 |
+ configWindow += "<div><input id=Video_Conf_Extension class=UiInputText type=text placeholder='"+ lang.video_conference_extension_example +"' value='"+ getDbItem("VidConfExtension", "") +"'></div>"; |
|
1458 |
+ configWindow += "<br><div class=UiText>"+ lang.video_conference_window_width +":</div>"; |
|
1459 |
+ configWindow += "<div><input id=Video_Conf_Window_Width class=UiInputText type=text placeholder='"+ lang.video_conf_window_width_explanation +"' value='"+ getDbItem("VidConfWindowWidth", "") +"'></div>"; |
|
1460 |
+ if (getDbItem("userrole", "") == "superadmin") { |
|
1461 |
+ |
|
1462 |
+ configWindow += "<div id=confTableSection>"+ lang.external_conf_users +"</div>"; |
|
1463 |
+ configWindow += "<div class=confTable><table id=vidConfExternalTable>"; |
|
1464 |
+ configWindow += "<tr class=btnTableRow><td><label for=extConfExtension id=extensionThLabel class=confExtLabels>Extension</label></td><td><label for=extConfExtensionPass id=extPassThLabel class=confExtLabels>SIP Password</label></td><td><label for=extConfExtensionLink id=extLinkThLabel class=confExtLabels>Link</label></td></tr>"; |
|
1465 |
+ |
|
1466 |
+ for (var cqt = 0; cqt < getDbItem("externalUserConfElem", ""); cqt++) { |
|
1467 |
+ configWindow += "<tr class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension value='"+ getDbItem('extUserExtension-'+cqt, '') +"' disabled=\"disabled\" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass value='"+ getDbItem('extUserExtensionPass-'+cqt, '') +"' disabled=\"disabled\"/></td><td><input type=text class=extConfExtensionLink name=extConfExtensionLink value='"+ getDbItem('confAccessLink-'+cqt, '') +"' /></td><td><span class=\"copyToClipboard\"><i class=\"fa fa-clipboard\" aria-hidden=\"true\" title=\"Copy link to clipboard.\"></i></span></td><td><span class=\"deleteExtRow\" title=\"Delete extension data from database.\">X</span></td><td><input type=submit class=saveExtConfExtension value=\"Edit\" title=\"Edit this row.\" /></td></tr>"; |
|
1468 |
+ } |
|
1469 |
+ |
|
1470 |
+ configWindow += "<tr id=emptyExtRow class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension placeholder=\"Eg: 711\" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass placeholder=\"Eg: d5?W?9q?8rg*R9!eFrVth?9\" /></td><td><input type=text class=extConfExtensionLink name=extConfExtensionLink placeholder=\"Generated on 'Save'\" disabled=\"disabled\" /></td><td><span class=\"copyToClipboard\"><i class=\"fa fa-clipboard\" aria-hidden=\"true\" title=\"Copy link to clipboard.\"></i></span></td><td><span class=\"deleteExtRow deleteExtRowDisabled\" title=\"Delete extension data from database.\">X</span></td><td><input type=submit class=saveExtConfExtension value=Save title=\"Save this row.\" /></td></tr>"; |
|
1471 |
+ configWindow += "</table></div>"; |
|
1472 |
+ configWindow += "<button id=add_New_External_User>Add External User</button>"; |
|
1473 |
+ } |
|
1474 |
+ configWindow += "<br><br></div>"; |
|
1475 |
+ |
|
1476 |
+ configWindow += "<div id=\"AppearanceHtml\" class=\"settingsSubSection\" style=\"display:none;\">"; |
|
1477 |
+ configWindow += "<div id=ImageCanvas style=\"width:150px; height:150px;\"></div>"; |
|
1478 |
+ configWindow += "<label for=fileUploader class=customBrowseButton style=\"margin-left: 200px; margin-top: -2px;\">Select File</label>"; |
|
1479 |
+ configWindow += "<div><input id=fileUploader type=file></div>"; |
|
1480 |
+ configWindow += "<div style=\"margin-top: 50px\"></div>"; |
|
1481 |
+ configWindow += "</div>"; |
|
1482 |
+ |
|
1483 |
+ configWindow += "<div id=\"NotificationsHtml\" class=\"settingsSubSection\" style=\"display:none;\">"; |
|
1484 |
+ configWindow += "<div class=UiText>"+ lang.notifications +":</div>"; |
|
1485 |
+ configWindow += "<div id=\"notificationsCheck\"><input type=checkbox id=Settings_Notifications><label for=Settings_Notifications> "+ lang.enable_onscreen_notifications +"<label></div>"; |
|
1486 |
+ configWindow += "</div>"; |
|
1487 |
+ |
|
1488 |
+ configWindow += "<div id=\"RoundcubeEmailHtml\" class=\"settingsSubSection\" style=\"display:none;\">"; |
|
1489 |
+ configWindow += "<div class=UiText>"+ lang.email_integration +":</div>"; |
|
1490 |
+ configWindow += "<div id=\"enableRCcheck\"><input id=emailIntegration type=checkbox ><label for=emailIntegration> "+ lang.enable_roundcube_integration +"<label></div>"; |
|
1491 |
+ configWindow += "<div class=UiText>"+ lang.roundcube_domain +":</div>"; |
|
1492 |
+ configWindow += "<div><input id=RoundcubeDomain class=UiInputText type=text placeholder='Roundcube domain (Eg: mail.example.com).' value='"+ getDbItem("rcDomain", "") +"'></div>"; |
|
1493 |
+ configWindow += "<div class=UiText>"+ lang.roundcube_user +":</div>"; |
|
1494 |
+ configWindow += "<div><input id=RoundcubeUser class=UiInputText type=text placeholder='Roundcube login user (Eg: john.doe@example.com or john_doe).' value='"+ getDbItem("RoundcubeUser", "") +"'></div>"; |
|
1495 |
+ configWindow += "<div class=UiText>"+ lang.roundcube_password +":</div>"; |
|
1496 |
+ configWindow += "<div><input id=RoundcubePass class=UiInputText type=password placeholder='Roundcube login password.' value='"+ getDbItem("RoundcubePass", "") +"'></div>"; |
|
1497 |
+ configWindow += "<div class=UiText>"+ lang.rc_basic_auth_user +":</div>"; |
|
1498 |
+ configWindow += "<div><input id=rcBasicAuthUser class=UiInputText type=text placeholder='If you have a Roundcube basic auth user, enter it here.' value='"+ getDbItem("rcBasicAuthUser", "") +"'></div>"; |
|
1499 |
+ configWindow += "<div class=UiText>"+ lang.rc_basic_auth_password +":</div>"; |
|
1500 |
+ configWindow += "<div><input id=rcBasicAuthPass class=UiInputText type=password placeholder='If you have a Roundcube basic auth password, enter it here.' value='"+ getDbItem("rcBasicAuthPass", "") +"'></div>"; |
|
1501 |
+ |
|
1502 |
+ configWindow += "<br><br></div>"; |
|
1503 |
+ |
|
1504 |
+ configWindow += "<div id=\"ChangePasswordHtml\" class=\"settingsSubSection\" style=\"display:none;\">"; |
|
1505 |
+ configWindow += "<div class=UiText>"+ lang.current_user_password +":</div>"; |
|
1506 |
+ configWindow += "<div><input id=Current_User_Password class=UiInputText type=password placeholder='Enter your current Roundpin user password.' value=''></div>"; |
|
1507 |
+ configWindow += "<div class=UiText>"+ lang.new_user_password +":</div>"; |
|
1508 |
+ configWindow += "<div><input id=New_User_Password class=UiInputText type=password placeholder='Enter your new Roundpin user password.' value=''></div>"; |
|
1509 |
+ configWindow += "<div class=UiText>"+ lang.repeat_new_user_password +":</div>"; |
|
1510 |
+ configWindow += "<div><input id=Repeat_New_User_Password class=UiInputText type=password placeholder='Enter your new Roundpin user password again.' value=''></div><br>"; |
|
1511 |
+ configWindow += "<div><input id=Save_New_User_Password type=button value='Save New Password' onclick='saveNewUserPassword()' ></div>"; |
|
1512 |
+ configWindow += "<br><br></div>"; |
|
1513 |
+ |
|
1514 |
+ configWindow += "<div id=\"ChangeEmailHtml\" class=\"settingsSubSection\" style=\"display:none;\">"; |
|
1515 |
+ configWindow += "<div class=UiText>"+ lang.current_user_email +":</div>"; |
|
1516 |
+ configWindow += "<div><input id=Current_User_Email class=UiInputText type=text placeholder='Enter your current Roundpin email address.' value=''></div>"; |
|
1517 |
+ configWindow += "<div class=UiText>"+ lang.new_user_email +":</div>"; |
|
1518 |
+ configWindow += "<div><input id=New_User_Email class=UiInputText type=text placeholder='Enter your new email address.' value=''></div>"; |
|
1519 |
+ configWindow += "<div class=UiText>"+ lang.repeat_new_user_email +":</div>"; |
|
1520 |
+ configWindow += "<div><input id=Repeat_New_User_Email class=UiInputText type=text placeholder='Enter your new email address again.' value=''></div><br>"; |
|
1521 |
+ configWindow += "<div><input id=Save_New_User_Email type=button value='Save New Email' onclick='saveNewUserEmail()' ></div>"; |
|
1522 |
+ configWindow += "<br><br></div>"; |
|
1523 |
+ |
|
1524 |
+ configWindow += "<div id=\"CloseAccountHtml\" class=\"settingsSubSection\" style=\"display:none;\">"; |
|
1525 |
+ configWindow += "<div class=UiText>"+ lang.if_you_want_to_close_account +":</div><br><br>"; |
|
1526 |
+ configWindow += "<div><input id=Close_User_Account type=button value='Close User Account' onclick='closeUserAccount()' ></div>"; |
|
1527 |
+ configWindow += "<br><br></div>"; |
|
1528 |
+ |
|
1529 |
+ configWindow += "</div></div></div>"; |
|
1530 |
+ |
|
1531 |
+ var settingsSections = "<table id=leftPanelSettings cellspacing=14 cellpadding=0 style=\"width:184px;margin-left:8px;margin-top:14px;font-size:15px;\">"; |
|
1532 |
+ settingsSections += "<tr id=ConnectionSettingsRow><td class=SettingsSection>Connection Settings</td></tr>"; |
|
1533 |
+ settingsSections += "<tr id=AudioAndVideoRow><td class=SettingsSection>Audio & Video</td></tr>"; |
|
1534 |
+ settingsSections += "<tr id=ProfilePictureRow><td class=SettingsSection>Profile Picture</td></tr>"; |
|
1535 |
+ settingsSections += "<tr id=NotificationsRow><td class=SettingsSection>Notifications</td></tr>"; |
|
1536 |
+ settingsSections += "<tr id=RoundcubeEmailRow><td class=SettingsSection>Email Integration</td></tr>"; |
|
1537 |
+ settingsSections += "<tr id=ChangePasswordRow><td class=SettingsSection>Change Password</td></tr>"; |
|
1538 |
+ settingsSections += "<tr id=ChangeEmailRow><td class=SettingsSection>Change Email</td></tr>"; |
|
1539 |
+ settingsSections += "<tr id=CloseAccountRow><td class=SettingsSection>Close Account</td></tr></table>"; |
|
1540 |
+ |
|
1541 |
+ $.jeegoopopup.open({ |
|
1542 |
+ title: '<span id=settingsTitle>Settings</span>', |
|
1543 |
+ html: configWindow, |
|
1544 |
+ width: '520', |
|
1545 |
+ height: '500', |
|
1546 |
+ center: true, |
|
1547 |
+ scrolling: 'no', |
|
1548 |
+ skinClass: 'jg_popup_basic', |
|
1549 |
+ contentClass: 'configPopup', |
|
1550 |
+ overlay: true, |
|
1551 |
+ opacity: 50, |
|
1552 |
+ draggable: true, |
|
1553 |
+ resizable: false, |
|
1554 |
+ fadeIn: 0 |
|
1555 |
+ }); |
|
1556 |
+ |
|
1557 |
+ $("#jg_popup_b").append('<div id="bottomButtonsConf"><button id="save_button_conf">Save</button><button id="cancel_button_conf">Cancel</button></div>'); |
|
1558 |
+ $("#jg_popup_l").append(settingsSections); |
|
1559 |
+ |
|
1560 |
+ if (getDbItem("useRoundcube", "") == 1) { $("#emailIntegration").prop("checked", true); } else { $("#emailIntegration").prop("checked", false); } |
|
1561 |
+ |
|
1562 |
+ $("#ConnectionSettingsRow td").addClass("selectedSettingsSection"); |
|
1563 |
+ |
|
1564 |
+ $("#ConnectionSettingsRow").click(function() { |
|
1565 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
1566 |
+ $("#AccountHtml").css("display", "block"); |
|
1567 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
1568 |
+ $("#ConnectionSettingsRow td").addClass("selectedSettingsSection"); |
|
1569 |
+ }); |
|
1570 |
+ |
|
1571 |
+ $("#ProfilePictureRow").click(function() { |
|
1572 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
1573 |
+ $("#AppearanceHtml").css("display", "block"); |
|
1574 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
1575 |
+ $("#ProfilePictureRow td").addClass("selectedSettingsSection"); |
|
1576 |
+ }); |
|
1577 |
+ |
|
1578 |
+ $("#NotificationsRow").click(function() { |
|
1579 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
1580 |
+ $("#NotificationsHtml").css("display", "block"); |
|
1581 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
1582 |
+ $("#NotificationsRow td").addClass("selectedSettingsSection"); |
|
1583 |
+ }); |
|
1584 |
+ |
|
1585 |
+ $("#RoundcubeEmailRow").click(function() { |
|
1586 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
1587 |
+ $("#RoundcubeEmailHtml").css("display", "block"); |
|
1588 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
1589 |
+ $("#RoundcubeEmailRow td").addClass("selectedSettingsSection"); |
|
1590 |
+ }); |
|
1591 |
+ |
|
1592 |
+ $("#ChangePasswordRow").click(function() { |
|
1593 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
1594 |
+ $("#ChangePasswordHtml").css("display", "block"); |
|
1595 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
1596 |
+ $("#ChangePasswordRow td").addClass("selectedSettingsSection"); |
|
1597 |
+ }); |
|
1598 |
+ |
|
1599 |
+ $("#ChangeEmailRow").click(function() { |
|
1600 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
1601 |
+ $("#ChangeEmailHtml").css("display", "block"); |
|
1602 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
1603 |
+ $("#ChangeEmailRow td").addClass("selectedSettingsSection"); |
|
1604 |
+ }); |
|
1605 |
+ |
|
1606 |
+ $("#CloseAccountRow").click(function() { |
|
1607 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
1608 |
+ $("#CloseAccountHtml").css("display", "block"); |
|
1609 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
1610 |
+ $("#CloseAccountRow td").addClass("selectedSettingsSection"); |
|
1611 |
+ }); |
|
1612 |
+ |
|
1613 |
+ var maxWidth = $(window).width() - 192; |
|
1614 |
+ var maxHeight = $(window).height() - 98; |
|
1615 |
+ |
|
1616 |
+ if (maxWidth < 520 || maxHeight < 500) { |
|
1617 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
1618 |
+ $.jeegoopopup.center(); |
|
1619 |
+ $("#maximizeImg").hide(); |
|
1620 |
+ $("#minimizeImg").hide(); |
|
1621 |
+ } else { |
|
1622 |
+ $.jeegoopopup.width(520).height(500); |
|
1623 |
+ $.jeegoopopup.center(); |
|
1624 |
+ $("#minimizeImg").hide(); |
|
1625 |
+ $("#maximizeImg").show(); |
|
1626 |
+ } |
|
1627 |
+ |
|
1628 |
+ $(window).resize(function() { |
|
1629 |
+ maxWidth = $(window).width() - 192; |
|
1630 |
+ maxHeight = $(window).height() - 98; |
|
1631 |
+ $.jeegoopopup.center(); |
|
1632 |
+ if (maxWidth < 520 || maxHeight < 500) { |
|
1633 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
1634 |
+ $.jeegoopopup.center(); |
|
1635 |
+ $("#maximizeImg").hide(); |
|
1636 |
+ $("#minimizeImg").hide(); |
|
1637 |
+ } else { |
|
1638 |
+ $.jeegoopopup.width(520).height(500); |
|
1639 |
+ $.jeegoopopup.center(); |
|
1640 |
+ $("#minimizeImg").hide(); |
|
1641 |
+ $("#maximizeImg").show(); |
|
1642 |
+ } |
|
1643 |
+ }); |
|
1644 |
+ |
|
1645 |
+ $("#minimizeImg").click(function() { $.jeegoopopup.width(520).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); }); |
|
1646 |
+ $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); }); |
|
1647 |
+ |
|
1648 |
+ |
|
1649 |
+ // Output |
|
1650 |
+ var selectAudioScr = $("#playbackSrc"); |
|
1651 |
+ |
|
1652 |
+ var playButton = $("#preview_output_play"); |
|
1653 |
+ |
|
1654 |
+ var playRingButton = $("#preview_ringer_play"); |
|
1655 |
+ |
|
1656 |
+ var pauseButton = $("#preview_output_pause"); |
|
1657 |
+ |
|
1658 |
+ // Microphone |
|
1659 |
+ var selectMicScr = $("#microphoneSrc"); |
|
1660 |
+ $("#Settings_AutoGainControl").prop("checked", AutoGainControl); |
|
1661 |
+ $("#Settings_EchoCancellation").prop("checked", EchoCancellation); |
|
1662 |
+ $("#Settings_NoiseSuppression").prop("checked", NoiseSuppression); |
|
1663 |
+ |
|
1664 |
+ // Webcam |
|
1665 |
+ var selectVideoScr = $("#previewVideoSrc"); |
|
1666 |
+ |
|
1667 |
+ // Orientation |
|
1668 |
+ var OrientationSel = $("input[name=Settings_Oriteation]"); |
|
1669 |
+ OrientationSel.each(function(){ |
|
1670 |
+ if(this.value == MirrorVideo) $(this).prop("checked", true); |
|
1671 |
+ }); |
|
1672 |
+ $("#local-video-preview").css("transform", MirrorVideo); |
|
1673 |
+ |
|
1674 |
+ // Frame Rate |
|
1675 |
+ var frameRateSel = $("input[name=Settings_FrameRate]"); |
|
1676 |
+ frameRateSel.each(function(){ |
|
1677 |
+ if(this.value == maxFrameRate) $(this).prop("checked", true); |
|
1678 |
+ }); |
|
1679 |
+ |
|
1680 |
+ // Quality |
|
1681 |
+ var QualitySel = $("input[name=Settings_Quality]"); |
|
1682 |
+ QualitySel.each(function(){ |
|
1683 |
+ if(this.value == videoHeight) $(this).prop("checked", true); |
|
1684 |
+ }); |
|
1685 |
+ |
|
1686 |
+ // Aspect Ratio |
|
1687 |
+ var AspectRatioSel = $("input[name=Settings_AspectRatio]"); |
|
1688 |
+ AspectRatioSel.each(function(){ |
|
1689 |
+ if(this.value == videoAspectRatio) $(this).prop("checked", true); |
|
1690 |
+ }); |
|
1691 |
+ |
|
1692 |
+ // Ring Tone |
|
1693 |
+ var selectRingTone = $("#ringTone"); |
|
1694 |
+ |
|
1695 |
+ // Ring Device |
|
1696 |
+ var selectRingDevice = $("#ringDevice"); |
|
1697 |
+ |
|
1698 |
+ // Handle Aspect Ratio Change |
|
1699 |
+ AspectRatioSel.change(function(){ |
|
1700 |
+ console.log("Call to change Aspect Ratio ("+ this.value +")"); |
|
1701 |
+ |
|
1702 |
+ var localVideo = $("#local-video-preview").get(0); |
|
1703 |
+ localVideo.muted = true; |
|
1704 |
+ localVideo.playsinline = true; |
|
1705 |
+ localVideo.autoplay = true; |
|
1706 |
+ |
|
1707 |
+ var tracks = localVideo.srcObject.getTracks(); |
|
1708 |
+ tracks.forEach(function(track) { |
|
1709 |
+ track.stop(); |
|
1710 |
+ }); |
|
1711 |
+ |
|
1712 |
+ var constraints = { |
|
1713 |
+ audio: false, |
|
1714 |
+ video: { |
|
1715 |
+ deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" |
|
1716 |
+ } |
|
1717 |
+ } |
|
1718 |
+ if($("input[name=Settings_FrameRate]:checked").val() != ""){ |
|
1719 |
+ constraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val(); |
|
1720 |
+ } |
|
1721 |
+ if($("input[name=Settings_Quality]:checked").val() != ""){ |
|
1722 |
+ constraints.video.height = $("input[name=Settings_Quality]:checked").val(); |
|
1723 |
+ } |
|
1724 |
+ if(this.value != ""){ |
|
1725 |
+ constraints.video.aspectRatio = this.value; |
|
1726 |
+ } |
|
1727 |
+ console.log("Constraints:", constraints); |
|
1728 |
+ var localStream = new MediaStream(); |
|
1729 |
+ if(navigator.mediaDevices){ |
|
1730 |
+ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ |
|
1731 |
+ var videoTrack = newStream.getVideoTracks()[0]; |
|
1732 |
+ localStream.addTrack(videoTrack); |
|
1733 |
+ localVideo.srcObject = localStream; |
|
1734 |
+ localVideo.onloadedmetadata = function(e) { |
|
1735 |
+ localVideo.play(); |
|
1736 |
+ } |
|
1737 |
+ }).catch(function(e){ |
|
1738 |
+ console.error(e); |
|
1739 |
+ AlertConfigExtWindow(lang.alert_error_user_media, lang.error); |
|
1740 |
+ }); |
|
1741 |
+ } |
|
1742 |
+ }); |
|
1743 |
+ |
|
1744 |
+ // Handle Video Height Change |
|
1745 |
+ QualitySel.change(function(){ |
|
1746 |
+ console.log("Call to change Video Height ("+ this.value +")"); |
|
1747 |
+ |
|
1748 |
+ var localVideo = $("#local-video-preview").get(0); |
|
1749 |
+ localVideo.muted = true; |
|
1750 |
+ localVideo.playsinline = true; |
|
1751 |
+ localVideo.autoplay = true; |
|
1752 |
+ |
|
1753 |
+ var tracks = localVideo.srcObject.getTracks(); |
|
1754 |
+ tracks.forEach(function(track) { |
|
1755 |
+ track.stop(); |
|
1756 |
+ }); |
|
1757 |
+ |
|
1758 |
+ var constraints = { |
|
1759 |
+ audio: false, |
|
1760 |
+ video: { |
|
1761 |
+ deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" , |
|
1762 |
+ } |
|
1763 |
+ } |
|
1764 |
+ if($("input[name=Settings_FrameRate]:checked").val() != ""){ |
|
1765 |
+ constraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val(); |
|
1766 |
+ } |
|
1767 |
+ if(this.value){ |
|
1768 |
+ constraints.video.height = this.value; |
|
1769 |
+ } |
|
1770 |
+ if($("input[name=Settings_AspectRatio]:checked").val() != ""){ |
|
1771 |
+ constraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val(); |
|
1772 |
+ } |
|
1773 |
+ console.log("Constraints:", constraints); |
|
1774 |
+ var localStream = new MediaStream(); |
|
1775 |
+ if(navigator.mediaDevices){ |
|
1776 |
+ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ |
|
1777 |
+ var videoTrack = newStream.getVideoTracks()[0]; |
|
1778 |
+ localStream.addTrack(videoTrack); |
|
1779 |
+ localVideo.srcObject = localStream; |
|
1780 |
+ localVideo.onloadedmetadata = function(e) { |
|
1781 |
+ localVideo.play(); |
|
1782 |
+ } |
|
1783 |
+ }).catch(function(e){ |
|
1784 |
+ console.error(e); |
|
1785 |
+ AlertConfigExtWindow(lang.alert_error_user_media, lang.error); |
|
1786 |
+ }); |
|
1787 |
+ } |
|
1788 |
+ }); |
|
1789 |
+ |
|
1790 |
+ // Handle Frame Rate Change |
|
1791 |
+ frameRateSel.change(function(){ |
|
1792 |
+ console.log("Call to change Frame Rate ("+ this.value +")"); |
|
1793 |
+ |
|
1794 |
+ var localVideo = $("#local-video-preview").get(0); |
|
1795 |
+ localVideo.muted = true; |
|
1796 |
+ localVideo.playsinline = true; |
|
1797 |
+ localVideo.autoplay = true; |
|
1798 |
+ |
|
1799 |
+ var tracks = localVideo.srcObject.getTracks(); |
|
1800 |
+ tracks.forEach(function(track) { |
|
1801 |
+ track.stop(); |
|
1802 |
+ }); |
|
1803 |
+ |
|
1804 |
+ var constraints = { |
|
1805 |
+ audio: false, |
|
1806 |
+ video: { |
|
1807 |
+ deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" , |
|
1808 |
+ } |
|
1809 |
+ } |
|
1810 |
+ if(this.value != ""){ |
|
1811 |
+ constraints.video.frameRate = this.value; |
|
1812 |
+ } |
|
1813 |
+ if($("input[name=Settings_Quality]:checked").val() != ""){ |
|
1814 |
+ constraints.video.height = $("input[name=Settings_Quality]:checked").val(); |
|
1815 |
+ } |
|
1816 |
+ if($("input[name=Settings_AspectRatio]:checked").val() != ""){ |
|
1817 |
+ constraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val(); |
|
1818 |
+ } |
|
1819 |
+ console.log("Constraints:", constraints); |
|
1820 |
+ var localStream = new MediaStream(); |
|
1821 |
+ if(navigator.mediaDevices){ |
|
1822 |
+ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ |
|
1823 |
+ var videoTrack = newStream.getVideoTracks()[0]; |
|
1824 |
+ localStream.addTrack(videoTrack); |
|
1825 |
+ localVideo.srcObject = localStream; |
|
1826 |
+ localVideo.onloadedmetadata = function(e) { |
|
1827 |
+ localVideo.play(); |
|
1828 |
+ } |
|
1829 |
+ }).catch(function(e){ |
|
1830 |
+ console.error(e); |
|
1831 |
+ AlertConfigExtWindow(lang.alert_error_user_media, lang.error); |
|
1832 |
+ }); |
|
1833 |
+ } |
|
1834 |
+ }); |
|
1835 |
+ |
|
1836 |
+ // Handle Audio Source changes (Microphone) |
|
1837 |
+ selectMicScr.change(function(){ |
|
1838 |
+ console.log("Call to change Microphone ("+ this.value +")"); |
|
1839 |
+ |
|
1840 |
+ // Change and update visual preview |
|
1841 |
+ try{ |
|
1842 |
+ var tracks = window.SettingsMicrophoneStream.getTracks(); |
|
1843 |
+ tracks.forEach(function(track) { |
|
1844 |
+ track.stop(); |
|
1845 |
+ }); |
|
1846 |
+ window.SettingsMicrophoneStream = null; |
|
1847 |
+ } |
|
1848 |
+ catch(e){} |
|
1849 |
+ |
|
1850 |
+ try{ |
|
1851 |
+ soundMeter = window.SettingsMicrophoneSoundMeter; |
|
1852 |
+ soundMeter.stop(); |
|
1853 |
+ window.SettingsMicrophoneSoundMeter = null; |
|
1854 |
+ } |
|
1855 |
+ catch(e){} |
|
1856 |
+ |
|
1857 |
+ // Get Microphone |
|
1858 |
+ var constraints = { |
|
1859 |
+ audio: { |
|
1860 |
+ deviceId: { exact: this.value } |
|
1861 |
+ }, |
|
1862 |
+ video: false |
|
1863 |
+ } |
|
1864 |
+ var localMicrophoneStream = new MediaStream(); |
|
1865 |
+ navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream){ |
|
1866 |
+ var audioTrack = mediaStream.getAudioTracks()[0]; |
|
1867 |
+ if(audioTrack != null){ |
|
1868 |
+ // Display Microphone Levels |
|
1869 |
+ localMicrophoneStream.addTrack(audioTrack); |
|
1870 |
+ window.SettingsMicrophoneStream = localMicrophoneStream; |
|
1871 |
+ window.SettingsMicrophoneSoundMeter = MeterSettingsOutput(localMicrophoneStream, "Settings_MicrophoneOutput", "width", 50); |
|
1872 |
+ } |
|
1873 |
+ }).catch(function(e){ |
|
1874 |
+ console.log("Failed to getUserMedia", e); |
|
1875 |
+ }); |
|
1876 |
+ }); |
|
1877 |
+ |
|
1878 |
+ // Handle output change (speaker) |
|
1879 |
+ selectAudioScr.change(function(){ |
|
1880 |
+ console.log("Call to change Speaker ("+ this.value +")"); |
|
1881 |
+ |
|
1882 |
+ var audioObj = window.SettingsOutputAudio; |
|
1883 |
+ if(audioObj != null) { |
|
1884 |
+ if (typeof audioObj.sinkId !== 'undefined') { |
|
1885 |
+ audioObj.setSinkId(this.value).then(function() { |
|
1886 |
+ console.log("sinkId applied to audioObj:", this.value); |
|
1887 |
+ }).catch(function(e){ |
|
1888 |
+ console.warn("Failed not apply setSinkId.", e); |
|
1889 |
+ }); |
|
1890 |
+ } |
|
1891 |
+ } |
|
1892 |
+ }); |
|
1893 |
+ |
|
1894 |
+ // Play button press |
|
1895 |
+ playButton.click(function(){ |
|
1896 |
+ |
|
1897 |
+ try{ |
|
1898 |
+ window.SettingsOutputAudio.pause(); |
|
1899 |
+ } |
|
1900 |
+ catch(e){} |
|
1901 |
+ window.SettingsOutputAudio = null; |
|
1902 |
+ |
|
1903 |
+ try{ |
|
1904 |
+ var tracks = window.SettingsOutputStream.getTracks(); |
|
1905 |
+ tracks.forEach(function(track) { |
|
1906 |
+ track.stop(); |
|
1907 |
+ }); |
|
1908 |
+ } |
|
1909 |
+ catch(e){} |
|
1910 |
+ window.SettingsOutputStream = null; |
|
1911 |
+ |
|
1912 |
+ try{ |
|
1913 |
+ var soundMeter = window.SettingsOutputStreamMeter; |
|
1914 |
+ soundMeter.stop(); |
|
1915 |
+ } |
|
1916 |
+ catch(e){} |
|
1917 |
+ window.SettingsOutputStreamMeter = null; |
|
1918 |
+ |
|
1919 |
+ // Load Sample |
|
1920 |
+ console.log("Audio:", audioBlobs.speaker_test.url); |
|
1921 |
+ var audioObj = new Audio(audioBlobs.speaker_test.blob); |
|
1922 |
+ audioObj.preload = "auto"; |
|
1923 |
+ audioObj.onplay = function(){ |
|
1924 |
+ var outputStream = new MediaStream(); |
|
1925 |
+ if (typeof audioObj.captureStream !== 'undefined') { |
|
1926 |
+ outputStream = audioObj.captureStream(); |
|
1927 |
+ } |
|
1928 |
+ else if (typeof audioObj.mozCaptureStream !== 'undefined') { |
|
1929 |
+ return; |
|
1930 |
+ } |
|
1931 |
+ else if (typeof audioObj.webkitCaptureStream !== 'undefined') { |
|
1932 |
+ outputStream = audioObj.webkitCaptureStream(); |
|
1933 |
+ } |
|
1934 |
+ else { |
|
1935 |
+ console.warn("Cannot display Audio Levels") |
|
1936 |
+ return; |
|
1937 |
+ } |
|
1938 |
+ |
|
1939 |
+ // Display Speaker Levels |
|
1940 |
+ window.SettingsOutputStream = outputStream; |
|
1941 |
+ window.SettingsOutputStreamMeter = MeterSettingsOutput(outputStream, "Settings_SpeakerOutput", "width", 50); |
|
1942 |
+ } |
|
1943 |
+ audioObj.oncanplaythrough = function(e) { |
|
1944 |
+ if (typeof audioObj.sinkId !== 'undefined') { |
|
1945 |
+ audioObj.setSinkId(selectAudioScr.val()).then(function() { |
|
1946 |
+ console.log("Set sinkId to:", selectAudioScr.val()); |
|
1947 |
+ }).catch(function(e){ |
|
1948 |
+ console.warn("Failed not apply setSinkId.", e); |
|
1949 |
+ }); |
|
1950 |
+ } |
|
1951 |
+ // Play |
|
1952 |
+ audioObj.play().then(function(){ |
|
1953 |
+ // Audio Is Playing |
|
1954 |
+ }).catch(function(e){ |
|
1955 |
+ console.warn("Unable to play audio file", e); |
|
1956 |
+ }); |
|
1957 |
+ console.log("Playing sample audio file... "); |
|
1958 |
+ } |
|
1959 |
+ |
|
1960 |
+ window.SettingsOutputAudio = audioObj; |
|
1961 |
+ }); |
|
1962 |
+ |
|
1963 |
+ // Pause button press |
|
1964 |
+ pauseButton.click(function() { |
|
1965 |
+ if (window.SettingsOutputAudio.paused) { |
|
1966 |
+ window.SettingsOutputAudio.play(); |
|
1967 |
+ } else { |
|
1968 |
+ window.SettingsOutputAudio.pause(); |
|
1969 |
+ } |
|
1970 |
+ }); |
|
1971 |
+ |
|
1972 |
+ |
|
1973 |
+ playRingButton.click(function(){ |
|
1974 |
+ |
|
1975 |
+ try{ |
|
1976 |
+ window.SettingsRingerAudio.pause(); |
|
1977 |
+ } |
|
1978 |
+ catch(e){} |
|
1979 |
+ window.SettingsRingerAudio = null; |
|
1980 |
+ |
|
1981 |
+ try{ |
|
1982 |
+ var tracks = window.SettingsRingerStream.getTracks(); |
|
1983 |
+ tracks.forEach(function(track) { |
|
1984 |
+ track.stop(); |
|
1985 |
+ }); |
|
1986 |
+ } |
|
1987 |
+ catch(e){} |
|
1988 |
+ window.SettingsRingerStream = null; |
|
1989 |
+ |
|
1990 |
+ try{ |
|
1991 |
+ var soundMeter = window.SettingsRingerStreamMeter; |
|
1992 |
+ soundMeter.stop(); |
|
1993 |
+ } |
|
1994 |
+ catch(e){} |
|
1995 |
+ window.SettingsRingerStreamMeter = null; |
|
1996 |
+ |
|
1997 |
+ // Load Sample |
|
1998 |
+ console.log("Audio:", audioBlobs.Ringtone.url); |
|
1999 |
+ var audioObj = new Audio(audioBlobs.Ringtone.blob); |
|
2000 |
+ audioObj.preload = "auto"; |
|
2001 |
+ audioObj.onplay = function(){ |
|
2002 |
+ var outputStream = new MediaStream(); |
|
2003 |
+ if (typeof audioObj.captureStream !== 'undefined') { |
|
2004 |
+ outputStream = audioObj.captureStream(); |
|
2005 |
+ } |
|
2006 |
+ else if (typeof audioObj.mozCaptureStream !== 'undefined') { |
|
2007 |
+ return; |
|
2008 |
+ // BUG: mozCaptureStream() in Firefox does not work the same way as captureStream() |
|
2009 |
+ // the actual sound does not play out to the speakers... its as if the mozCaptureStream |
|
2010 |
+ // removes the stream from the <audio> object. |
|
2011 |
+ outputStream = audioObj.mozCaptureStream(); |
|
2012 |
+ } |
|
2013 |
+ else if (typeof audioObj.webkitCaptureStream !== 'undefined') { |
|
2014 |
+ outputStream = audioObj.webkitCaptureStream(); |
|
2015 |
+ } |
|
2016 |
+ else { |
|
2017 |
+ console.warn("Cannot display Audio Levels") |
|
2018 |
+ return; |
|
2019 |
+ } |
|
2020 |
+ // Monitor Output |
|
2021 |
+ window.SettingsRingerStream = outputStream; |
|
2022 |
+ window.SettingsRingerStreamMeter = MeterSettingsOutput(outputStream, "Settings_RingerOutput", "width", 50); |
|
2023 |
+ } |
|
2024 |
+ audioObj.oncanplaythrough = function(e) { |
|
2025 |
+ if (typeof audioObj.sinkId !== 'undefined') { |
|
2026 |
+ audioObj.setSinkId(selectRingDevice.val()).then(function() { |
|
2027 |
+ console.log("Set sinkId to:", selectRingDevice.val()); |
|
2028 |
+ }).catch(function(e){ |
|
2029 |
+ console.warn("Failed not apply setSinkId.", e); |
|
2030 |
+ }); |
|
2031 |
+ } |
|
2032 |
+ // Play |
|
2033 |
+ audioObj.play().then(function(){ |
|
2034 |
+ // Audio Is Playing |
|
2035 |
+ }).catch(function(e){ |
|
2036 |
+ console.warn("Unable to play audio file", e); |
|
2037 |
+ }); |
|
2038 |
+ console.log("Playing sample audio file... "); |
|
2039 |
+ } |
|
2040 |
+ |
|
2041 |
+ window.SettingsRingerAudio = audioObj; |
|
2042 |
+ }); |
|
2043 |
+ |
|
2044 |
+ // Change Video Image |
|
2045 |
+ OrientationSel.change(function(){ |
|
2046 |
+ console.log("Call to change Orientation ("+ this.value +")"); |
|
2047 |
+ $("#local-video-preview").css("transform", this.value); |
|
2048 |
+ }); |
|
2049 |
+ |
|
2050 |
+ // Handle video input change (WebCam) |
|
2051 |
+ selectVideoScr.change(function(){ |
|
2052 |
+ console.log("Call to change WebCam ("+ this.value +")"); |
|
2053 |
+ |
|
2054 |
+ var localVideo = $("#local-video-preview").get(0); |
|
2055 |
+ localVideo.muted = true; |
|
2056 |
+ localVideo.playsinline = true; |
|
2057 |
+ localVideo.autoplay = true; |
|
2058 |
+ |
|
2059 |
+ var tracks = localVideo.srcObject.getTracks(); |
|
2060 |
+ tracks.forEach(function(track) { |
|
2061 |
+ track.stop(); |
|
2062 |
+ }); |
|
2063 |
+ |
|
2064 |
+ var constraints = { |
|
2065 |
+ audio: false, |
|
2066 |
+ video: { |
|
2067 |
+ deviceId: (this.value != "default")? { exact: this.value } : "default" |
|
2068 |
+ } |
|
2069 |
+ } |
|
2070 |
+ if($("input[name=Settings_FrameRate]:checked").val() != ""){ |
|
2071 |
+ constraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val(); |
|
2072 |
+ } |
|
2073 |
+ if($("input[name=Settings_Quality]:checked").val() != ""){ |
|
2074 |
+ constraints.video.height = $("input[name=Settings_Quality]:checked").val(); |
|
2075 |
+ } |
|
2076 |
+ if($("input[name=Settings_AspectRatio]:checked").val() != ""){ |
|
2077 |
+ constraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val(); |
|
2078 |
+ } |
|
2079 |
+ console.log("Constraints:", constraints); |
|
2080 |
+ var localStream = new MediaStream(); |
|
2081 |
+ if(navigator.mediaDevices){ |
|
2082 |
+ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ |
|
2083 |
+ var videoTrack = newStream.getVideoTracks()[0]; |
|
2084 |
+ localStream.addTrack(videoTrack); |
|
2085 |
+ localVideo.srcObject = localStream; |
|
2086 |
+ localVideo.onloadedmetadata = function(e) { |
|
2087 |
+ localVideo.play(); |
|
2088 |
+ } |
|
2089 |
+ }).catch(function(e){ |
|
2090 |
+ console.error(e); |
|
2091 |
+ AlertConfigExtWindow(lang.alert_error_user_media, lang.error); |
|
2092 |
+ }); |
|
2093 |
+ } |
|
2094 |
+ }); |
|
2095 |
+ |
|
2096 |
+ $("#AudioAndVideoRow").click(function() { |
|
2097 |
+ |
|
2098 |
+ $(".settingsSubSection").each(function() { $(this).css("display", "none"); }); |
|
2099 |
+ $("#AudioVideoHtml").css("display", "block"); |
|
2100 |
+ $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); }); |
|
2101 |
+ $("#AudioAndVideoRow td").addClass("selectedSettingsSection"); |
|
2102 |
+ |
|
2103 |
+ if (videoAudioCheck == 0) { |
|
2104 |
+ |
|
2105 |
+ videoAudioCheck = 1; |
|
2106 |
+ |
|
2107 |
+ // Note: Only works over HTTPS or via localhost!! |
|
2108 |
+ var localVideo = $("#local-video-preview").get(0); |
|
2109 |
+ localVideo.muted = true; |
|
2110 |
+ localVideo.playsinline = true; |
|
2111 |
+ localVideo.autoplay = true; |
|
2112 |
+ |
|
2113 |
+ var localVideoStream = new MediaStream(); |
|
2114 |
+ var localMicrophoneStream = new MediaStream(); |
|
2115 |
+ |
|
2116 |
+ if(navigator.mediaDevices){ |
|
2117 |
+ navigator.mediaDevices.enumerateDevices().then(function(deviceInfos){ |
|
2118 |
+ var savedVideoDevice = getVideoSrcID(); |
|
2119 |
+ var videoDeviceFound = false; |
|
2120 |
+ |
|
2121 |
+ var savedAudioDevice = getAudioSrcID(); |
|
2122 |
+ var audioDeviceFound = false; |
|
2123 |
+ |
|
2124 |
+ var MicrophoneFound = false; |
|
2125 |
+ var SpeakerFound = false; |
|
2126 |
+ var VideoFound = false; |
|
2127 |
+ |
|
2128 |
+ for (var i = 0; i < deviceInfos.length; ++i) { |
|
2129 |
+ console.log("Found Device ("+ deviceInfos[i].kind +"): ", deviceInfos[i].label); |
|
2130 |
+ |
|
2131 |
+ // Check Devices |
|
2132 |
+ if (deviceInfos[i].kind === "audioinput") { |
|
2133 |
+ MicrophoneFound = true; |
|
2134 |
+ if(savedAudioDevice != "default" && deviceInfos[i].deviceId == savedAudioDevice) { |
|
2135 |
+ audioDeviceFound = true; |
|
2136 |
+ } |
|
2137 |
+ } |
|
2138 |
+ else if (deviceInfos[i].kind === "audiooutput") { |
|
2139 |
+ SpeakerFound = true; |
|
2140 |
+ } |
|
2141 |
+ else if (deviceInfos[i].kind === "videoinput") { |
|
2142 |
+ VideoFound = true; |
|
2143 |
+ if(savedVideoDevice != "default" && deviceInfos[i].deviceId == savedVideoDevice) { |
|
2144 |
+ videoDeviceFound = true; |
|
2145 |
+ } |
|
2146 |
+ } |
|
2147 |
+ } |
|
2148 |
+ |
|
2149 |
+ var contraints = { |
|
2150 |
+ audio: MicrophoneFound, |
|
2151 |
+ video: VideoFound |
|
2152 |
+ } |
|
2153 |
+ |
|
2154 |
+ if(MicrophoneFound){ |
|
2155 |
+ contraints.audio = { deviceId: "default" } |
|
2156 |
+ if(audioDeviceFound) contraints.audio.deviceId = { exact: savedAudioDevice } |
|
2157 |
+ } |
|
2158 |
+ if(VideoFound){ |
|
2159 |
+ contraints.video = { deviceId: "default" } |
|
2160 |
+ if(videoDeviceFound) contraints.video.deviceId = { exact: savedVideoDevice } |
|
2161 |
+ } |
|
2162 |
+ // Additional |
|
2163 |
+ if($("input[name=Settings_FrameRate]:checked").val() != ""){ |
|
2164 |
+ contraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val(); |
|
2165 |
+ } |
|
2166 |
+ if($("input[name=Settings_Quality]:checked").val() != ""){ |
|
2167 |
+ contraints.video.height = $("input[name=Settings_Quality]:checked").val(); |
|
2168 |
+ } |
|
2169 |
+ if($("input[name=Settings_AspectRatio]:checked").val() != ""){ |
|
2170 |
+ contraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val(); |
|
2171 |
+ } |
|
2172 |
+ console.log("Get User Media", contraints); |
|
2173 |
+ // Get User Media |
|
2174 |
+ navigator.mediaDevices.getUserMedia(contraints).then(function(mediaStream){ |
|
2175 |
+ // Handle Video |
|
2176 |
+ var videoTrack = (mediaStream.getVideoTracks().length >= 1)? mediaStream.getVideoTracks()[0] : null; |
|
2177 |
+ if(VideoFound && videoTrack != null){ |
|
2178 |
+ localVideoStream.addTrack(videoTrack); |
|
2179 |
+ // Display Preview Video |
|
2180 |
+ localVideo.srcObject = localVideoStream; |
|
2181 |
+ localVideo.onloadedmetadata = function(e) { |
|
2182 |
+ localVideo.play(); |
|
2183 |
+ } |
|
2184 |
+ } |
|
2185 |
+ else { |
|
2186 |
+ console.warn("No video / webcam devices found. Video Calling will not be possible.") |
|
2187 |
+ } |
|
2188 |
+ |
|
2189 |
+ // Handle Audio |
|
2190 |
+ var audioTrack = (mediaStream.getAudioTracks().length >= 1)? mediaStream.getAudioTracks()[0] : null ; |
|
2191 |
+ if(MicrophoneFound && audioTrack != null){ |
|
2192 |
+ localMicrophoneStream.addTrack(audioTrack); |
|
2193 |
+ // Display Micrphone Levels |
|
2194 |
+ window.SettingsMicrophoneStream = localMicrophoneStream; |
|
2195 |
+ window.SettingsMicrophoneSoundMeter = MeterSettingsOutput(localMicrophoneStream, "Settings_MicrophoneOutput", "width", 50); |
|
2196 |
+ } |
|
2197 |
+ else { |
|
2198 |
+ console.warn("No microphone devices found. Calling will not be possible.") |
|
2199 |
+ } |
|
2200 |
+ |
|
2201 |
+ // Display Output Levels |
|
2202 |
+ $("#Settings_SpeakerOutput").css("width", "0%"); |
|
2203 |
+ if(!SpeakerFound){ |
|
2204 |
+ console.log("No speaker devices found, make sure one is plugged in.") |
|
2205 |
+ $("#playbackSrc").hide(); |
|
2206 |
+ $("#RingDeviceSection").hide(); |
|
2207 |
+ } |
|
2208 |
+ |
|
2209 |
+ // Return .then() |
|
2210 |
+ return navigator.mediaDevices.enumerateDevices(); |
|
2211 |
+ }).then(function(deviceInfos){ |
|
2212 |
+ for (var i = 0; i < deviceInfos.length; ++i) { |
|
2213 |
+ console.log("Found Device ("+ deviceInfos[i].kind +") Again: ", deviceInfos[i].label, deviceInfos[i].deviceId); |
|
2214 |
+ |
|
2215 |
+ var deviceInfo = deviceInfos[i]; |
|
2216 |
+ var devideId = deviceInfo.deviceId; |
|
2217 |
+ var DisplayName = deviceInfo.label; |
|
2218 |
+ if(DisplayName.indexOf("(") > 0) DisplayName = DisplayName.substring(0,DisplayName.indexOf("(")); |
|
2219 |
+ |
|
2220 |
+ var option = $('<option/>'); |
|
2221 |
+ option.prop("value", devideId); |
|
2222 |
+ |
|
2223 |
+ if (deviceInfo.kind === "audioinput") { |
|
2224 |
+ option.text((DisplayName != "")? DisplayName : "Microphone"); |
|
2225 |
+ if(getAudioSrcID() == devideId) option.prop("selected", true); |
|
2226 |
+ selectMicScr.append(option); |
|
2227 |
+ } |
|
2228 |
+ else if (deviceInfo.kind === "audiooutput") { |
|
2229 |
+ option.text((DisplayName != "")? DisplayName : "Speaker"); |
|
2230 |
+ if(getAudioOutputID() == devideId) option.prop("selected", true); |
|
2231 |
+ selectAudioScr.append(option); |
|
2232 |
+ selectRingDevice.append(option.clone()); |
|
2233 |
+ } |
|
2234 |
+ else if (deviceInfo.kind === "videoinput") { |
|
2235 |
+ if(getVideoSrcID() == devideId) option.prop("selected", true); |
|
2236 |
+ option.text((DisplayName != "")? DisplayName : "Webcam"); |
|
2237 |
+ selectVideoScr.append(option); |
|
2238 |
+ } |
|
2239 |
+ } |
|
2240 |
+ // Add "Default" option |
|
2241 |
+ if(selectVideoScr.children('option').length > 0){ |
|
2242 |
+ var option = $('<option/>'); |
|
2243 |
+ option.prop("value", "default"); |
|
2244 |
+ if(getVideoSrcID() == "default" || getVideoSrcID() == "" || getVideoSrcID() == "null") option.prop("selected", true); |
|
2245 |
+ option.text("(Default)"); |
|
2246 |
+ selectVideoScr.append(option); |
|
2247 |
+ } |
|
2248 |
+ }).catch(function(e){ |
|
2249 |
+ console.error(e); |
|
2250 |
+ AlertConfigExtWindow(lang.alert_error_user_media, lang.error); |
|
2251 |
+ }); |
|
2252 |
+ }).catch(function(e){ |
|
2253 |
+ console.error("Error getting Media Devices", e); |
|
2254 |
+ }); |
|
2255 |
+ |
|
2256 |
+ } else { |
|
2257 |
+ AlertConfigExtWindow(lang.alert_error_user_media, lang.error); |
|
2258 |
+ } |
|
2259 |
+ } |
|
2260 |
+ }); |
|
2261 |
+ |
|
2262 |
+ var NotificationsCheck = $("#Settings_Notifications"); |
|
2263 |
+ NotificationsCheck.prop("checked", NotificationsActive); |
|
2264 |
+ NotificationsCheck.change(function(){ |
|
2265 |
+ if(this.checked){ |
|
2266 |
+ if(Notification.permission != "granted"){ |
|
2267 |
+ if(checkNotificationPromise()){ |
|
2268 |
+ Notification.requestPermission().then(function(p){ |
|
2269 |
+ console.log(p); |
|
2270 |
+ HandleNotifyPermission(p); |
|
2271 |
+ }); |
|
2272 |
+ } |
|
2273 |
+ else { |
|
2274 |
+ Notification.requestPermission(function(p){ |
|
2275 |
+ console.log(p); |
|
2276 |
+ HandleNotifyPermission(p) |
|
2277 |
+ }); |
|
2278 |
+ } |
|
2279 |
+ } |
|
2280 |
+ } |
|
2281 |
+ }); |
|
2282 |
+ |
|
2283 |
+ |
|
2284 |
+ // Save configration data for external video conference users |
|
2285 |
+ $("#vidConfExternalTable").on("click", ".saveExtConfExtension", function() { |
|
2286 |
+ |
|
2287 |
+ if ($(this).val() == "Save") { |
|
2288 |
+ |
|
2289 |
+ var extUserExtension = $(this).closest('tr').find('input.extConfExtension').val(); |
|
2290 |
+ var extUserExtensionPass = $(this).closest('tr').find('input.extConfExtensionPass').val(); |
|
2291 |
+ |
|
2292 |
+ var WSSServer = localDB.getItem("wssServer"); |
|
2293 |
+ |
|
2294 |
+ if (extUserExtension != '' && extUserExtensionPass != '') { |
|
2295 |
+ if (extUserExtension.length < 200 && extUserExtensionPass.length < 400) { |
|
2296 |
+ // Check if the extension that has been entered is valid |
|
2297 |
+ if (/^[a-zA-Z0-9]+$/.test(extUserExtension)) { |
|
2298 |
+ |
|
2299 |
+ $.ajax({ |
|
2300 |
+ type: "POST", |
|
2301 |
+ url: "save-update-external-user-conf.php", |
|
2302 |
+ dataType: "JSON", |
|
2303 |
+ data: { |
|
2304 |
+ username: userName, |
|
2305 |
+ exten_for_external: extUserExtension, |
|
2306 |
+ exten_for_ext_pass: extUserExtensionPass, |
|
2307 |
+ wss_server: WSSServer, |
|
2308 |
+ s_ajax_call: validateSToken |
|
2309 |
+ }, |
|
2310 |
+ success: function(response) { |
|
2311 |
+ |
|
2312 |
+ if (response.result == 'The data has been successfully saved to the database !') { |
|
2313 |
+ |
|
2314 |
+ getExternalUserConfFromSqldb(); |
|
2315 |
+ alert("The data has been successfully saved to the database ! To see the result, please reopen this window !"); |
|
2316 |
+ |
|
2317 |
+ $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); closeVideoAudio(); $.jeegoopopup.close(); |
|
2318 |
+ |
|
2319 |
+ } else { alert(response.result); } |
|
2320 |
+ |
|
2321 |
+ }, |
|
2322 |
+ error: function(response) { |
|
2323 |
+ alert("An error occurred while trying to save the data to the database !"); |
|
2324 |
+ } |
|
2325 |
+ }); |
|
2326 |
+ |
|
2327 |
+ $(this).closest('[class="btnTableRow"]').find('[class="extConfExtension"]').attr("disabled", true); |
|
2328 |
+ $(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionPass"]').attr("disabled", true); |
|
2329 |
+ $(this).attr("value", "Edit"); |
|
2330 |
+ $(this).prop("title", "Edit this row."); |
|
2331 |
+ |
|
2332 |
+ } else { alert("The extension should contain only numbers and letters."); } |
|
2333 |
+ } else { alert("The extension and/or the SIP password don't have a reasonable length."); } |
|
2334 |
+ } else { alert("Please fill in both the \"Extension\" and the \"SIP Password\" fields !"); } |
|
2335 |
+ } else { |
|
2336 |
+ $(this).closest('[class="btnTableRow"]').find('[class="extConfExtension"]').attr("disabled", false); |
|
2337 |
+ $(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionPass"]').attr("disabled", false); |
|
2338 |
+ $(this).attr("value", "Save"); |
|
2339 |
+ $(this).prop("title", "Save this row."); |
|
2340 |
+ } |
|
2341 |
+ }); |
|
2342 |
+ |
|
2343 |
+ // Delete extension data from the database |
|
2344 |
+ $("#vidConfExternalTable").on("click", ".deleteExtRow", function() { |
|
2345 |
+ |
|
2346 |
+ var targetExtension = $(this).closest('[class="btnTableRow"]').find('[class="extConfExtension"]').val(); |
|
2347 |
+ |
|
2348 |
+ if (targetExtension != '') { |
|
2349 |
+ |
|
2350 |
+ if (confirm("Do you really want to delete this row from this window and from the database ?")) { |
|
2351 |
+ |
|
2352 |
+ $.ajax({ |
|
2353 |
+ type: "POST", |
|
2354 |
+ url: "remove-external-user-ext-data.php", |
|
2355 |
+ dataType: "JSON", |
|
2356 |
+ data: { |
|
2357 |
+ username: userName, |
|
2358 |
+ exten_for_external: targetExtension, |
|
2359 |
+ s_ajax_call: validateSToken |
|
2360 |
+ }, |
|
2361 |
+ success: function(response) { |
|
2362 |
+ $(this).closest('tr').find('input.extConfExtension').empty(); |
|
2363 |
+ $(this).closest('tr').find('input.extConfExtensionPass').empty(); |
|
2364 |
+ $(this).closest('tr').find('input.extConfExtensionLink').empty(); |
|
2365 |
+ getExternalUserConfFromSqldb(); |
|
2366 |
+ alert("The data has been permanently removed !"); |
|
2367 |
+ }, |
|
2368 |
+ error: function(response) { |
|
2369 |
+ alert("An error occurred while trying to remove the data !"); |
|
2370 |
+ } |
|
2371 |
+ }); |
|
2372 |
+ |
|
2373 |
+ $(this).closest('[class="btnTableRow"]').hide(); |
|
2374 |
+ } |
|
2375 |
+ } |
|
2376 |
+ }); |
|
2377 |
+ |
|
2378 |
+ $(".copyToClipboard").mouseenter(function() { |
|
2379 |
+ if ($(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionLink"]').val() != '') { |
|
2380 |
+ $(this).css("color", "#424242"); |
|
2381 |
+ $(this).css("cursor", "pointer"); |
|
2382 |
+ } |
|
2383 |
+ }); |
|
2384 |
+ |
|
2385 |
+ $(".copyToClipboard").mouseleave(function() { |
|
2386 |
+ $(this).css("color", "#cccccc"); |
|
2387 |
+ }); |
|
2388 |
+ |
|
2389 |
+ $(".copyToClipboard").click(function() { |
|
2390 |
+ if ($(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionLink"]').val() != '') { |
|
2391 |
+ var $tempEl = $("<input>"); |
|
2392 |
+ $("body").append($tempEl); |
|
2393 |
+ $tempEl.val($(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionLink"]').val()).select(); |
|
2394 |
+ document.execCommand("Copy"); |
|
2395 |
+ $tempEl.remove(); |
|
2396 |
+ alert("The link has been copied to your clipboard!"); |
|
2397 |
+ } |
|
2398 |
+ }); |
|
2399 |
+ |
|
2400 |
+ var externUserData = getDbItem("externalUserConfElem", ""); |
|
2401 |
+ if (externUserData !== 'undefined' && externUserData != 'null' && externUserData != 0) { |
|
2402 |
+ $("#emptyExtRow").hide(); |
|
2403 |
+ } |
|
2404 |
+ |
|
2405 |
+ $("#add_New_External_User").click(function() { |
|
2406 |
+ $("#vidConfExternalTable").append("<tr class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension placeholder=\"Eg: 711\" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass placeholder=\"Eg: d5?W?9q?8rg*R9!eFrVth?9\" /></td><td><input type=text class=\"extConfExtensionLink\" name=extConfExtensionLink placeholder=\"Generated on 'Save'\" disabled=\"disabled\" /></td><td><span class=\"copyToClipboard\"><i class=\"fa fa-clipboard\" aria-hidden=\"true\" title=\"Copy link to clipboard.\"></i></span></td><td><span class=\"deleteExtRow deleteExtRowDisabled\" title=\"Delete extension data from database.\">X</span></td><td><input type=submit class=\"saveExtConfExtension\" value=\"Save\" title=\"Save this row.\" /></td></tr>"); |
|
2407 |
+ }); |
|
2408 |
+ |
|
2409 |
+ |
|
2410 |
+ // Profile Picture |
|
2411 |
+ cropper = $("#ImageCanvas").croppie({ |
|
2412 |
+ viewport: { width: 150, height: 150, type: 'circle' } |
|
2413 |
+ }); |
|
2414 |
+ |
|
2415 |
+ // Preview Existing Image |
|
2416 |
+ $("#ImageCanvas").croppie('bind', { url: getPicture("profilePicture") }).then(function() { |
|
2417 |
+ $('.cr-slider').attr({ min: 0.5, max: 3 }); |
|
2418 |
+ }); |
|
2419 |
+ |
|
2420 |
+ // Wireup File Change |
|
2421 |
+ $("#fileUploader").change(function () { |
|
2422 |
+ var filesArray = $(this).prop('files'); |
|
2423 |
+ |
|
2424 |
+ if (filesArray.length == 1) { |
|
2425 |
+ var uploadId = Math.floor(Math.random() * 1000000000); |
|
2426 |
+ var fileObj = filesArray[0]; |
|
2427 |
+ var fileName = fileObj.name; |
|
2428 |
+ var fileSize = fileObj.size; |
|
2429 |
+ |
|
2430 |
+ if (fileSize <= 52428800) { |
|
2431 |
+ console.log("Adding (" + uploadId + "): " + fileName + " of size: " + fileSize + "bytes"); |
|
2432 |
+ |
|
2433 |
+ var reader = new FileReader(); |
|
2434 |
+ reader.Name = fileName; |
|
2435 |
+ reader.UploadId = uploadId; |
|
2436 |
+ reader.Size = fileSize; |
|
2437 |
+ reader.onload = function (event) { |
|
2438 |
+ $("#ImageCanvas").croppie('bind', { |
|
2439 |
+ url: event.target.result |
|
2440 |
+ }); |
|
2441 |
+ } |
|
2442 |
+ |
|
2443 |
+ // Use onload for this |
|
2444 |
+ reader.readAsDataURL(fileObj); |
|
2445 |
+ } |
|
2446 |
+ else { |
|
2447 |
+ Alert(lang.alert_file_size, lang.error); |
|
2448 |
+ } |
|
2449 |
+ } |
|
2450 |
+ else { |
|
2451 |
+ Alert(lang.alert_single_file, lang.error); |
|
2452 |
+ } |
|
2453 |
+ }); |
|
2454 |
+ |
|
2455 |
+ |
|
2456 |
+ $("#save_button_conf").click(function() { |
|
2457 |
+ |
|
2458 |
+ if(localDB.getItem("profileUserID") == null) localDB.setItem("profileUserID", uID()); // For first time only |
|
2459 |
+ |
|
2460 |
+ var confAccWssServer = $("#Configure_Account_wssServer").val(); |
|
2461 |
+ if (/^[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(confAccWssServer)) { var finconfAccWssServer = confAccWssServer; } else { |
|
2462 |
+ var finconfAccWssServer = ''; alert('The WebSocket domain that you entered is not a valid domain name!'); } |
|
2463 |
+ |
|
2464 |
+ var confAccWSPort = $("#Configure_Account_WebSocketPort").val(); |
|
2465 |
+ if (/^[0-9]+$/.test(confAccWSPort)) { var finConfAccWSPort = confAccWSPort; } else { |
|
2466 |
+ var finConfAccWSPort = ''; alert('The web socket port that you entered is not a valid port!'); } |
|
2467 |
+ |
|
2468 |
+ var confAccServerPath = $("#Configure_Account_ServerPath").val(); |
|
2469 |
+ if (/^[A-Za-z0-9\/]+$/.test(confAccServerPath)) { var finConfAccServerPath = confAccServerPath; } else { |
|
2470 |
+ var finConfAccServerPath = ''; alert('The server path that you entered is not a valid server path!');} |
|
2471 |
+ |
|
2472 |
+ var confAccProfileName = $("#Configure_Account_profileName").val(); |
|
2473 |
+ if (/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(confAccProfileName)) { var finConfAccProfileName = confAccProfileName; } else { |
|
2474 |
+ var finConfAccProfileName = ''; alert('The profile name that you entered is not a valid profile name!'); } |
|
2475 |
+ |
|
2476 |
+ var confAccSipUsername = $("#Configure_Account_SipUsername").val(); |
|
2477 |
+ if (/^[A-Za-z0-9\-\.\_\@\*\!\?\&\~\(\)\[\]]+$/.test(confAccSipUsername)) { var finConfAccSipUsername = confAccSipUsername; } else { |
|
2478 |
+ var finConfAccSipUsername = ''; alert('The SIP username that you entered is not a valid SIP username!'); } |
|
2479 |
+ |
|
2480 |
+ var confAccSipPassword = $("#Configure_Account_SipPassword").val(); |
|
2481 |
+ if (confAccSipPassword.length < 400) { var finConfAccSipPassword = confAccSipPassword; } else { |
|
2482 |
+ var finConfAccSipPassword = ''; alert('The SIP password that you entered is too long!'); } |
|
2483 |
+ |
|
2484 |
+ var confAccStun = $("#Configure_Account_StunServer").val(); |
|
2485 |
+ if (confAccStun != null && confAccStun.trim() !== '') { |
|
2486 |
+ if (/^(\d+\.\d+\.\d+\.\d+:\d+)$|^([A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}:\d+)/.test(confAccStun)) { var finConfAccStun = confAccStun; } else { |
|
2487 |
+ var finConfAccStun = ''; alert('The domain or IP or port number of the STUN server is not valid!'); } |
|
2488 |
+ } else { var finConfAccStun = ''; } |
|
2489 |
+ |
|
2490 |
+ if (finconfAccWssServer != null && finconfAccWssServer.trim() !== '' && |
|
2491 |
+ finConfAccWSPort != null && finConfAccWSPort.trim() !== '' && |
|
2492 |
+ finConfAccServerPath != null && finConfAccServerPath.trim() !== '' && |
|
2493 |
+ finConfAccProfileName != null && finConfAccProfileName.trim() !== '' && |
|
2494 |
+ finConfAccSipUsername != null && finConfAccSipUsername.trim() !== '' && |
|
2495 |
+ finConfAccSipPassword != null && finConfAccSipPassword.trim() !== '') { |
|
2496 |
+ |
|
2497 |
+ // OK |
|
2498 |
+ |
|
2499 |
+ } else { alert('All fields marked with an asterisk are required!'); return; } |
|
2500 |
+ |
|
2501 |
+ |
|
2502 |
+ // Audio & Video |
|
2503 |
+ localDB.setItem("AudioOutputId", $("#playbackSrc").val()); |
|
2504 |
+ localDB.setItem("VideoSrcId", $("#previewVideoSrc").val()); |
|
2505 |
+ localDB.setItem("VideoHeight", $("input[name=Settings_Quality]:checked").val()); |
|
2506 |
+ localDB.setItem("FrameRate", $("input[name=Settings_FrameRate]:checked").val()); |
|
2507 |
+ localDB.setItem("AspectRatio", $("input[name=Settings_AspectRatio]:checked").val()); |
|
2508 |
+ localDB.setItem("VideoOrientation", $("input[name=Settings_Oriteation]:checked").val()); |
|
2509 |
+ localDB.setItem("AudioSrcId", $("#microphoneSrc").val()); |
|
2510 |
+ localDB.setItem("AutoGainControl", ($("#Settings_AutoGainControl").is(':checked'))? "1" : "0"); |
|
2511 |
+ localDB.setItem("EchoCancellation", ($("#Settings_EchoCancellation").is(':checked'))? "1" : "0"); |
|
2512 |
+ localDB.setItem("NoiseSuppression", ($("#Settings_NoiseSuppression").is(':checked'))? "1" : "0"); |
|
2513 |
+ localDB.setItem("RingOutputId", $("#ringDevice").val()); |
|
2514 |
+ |
|
2515 |
+ // Check if the extension that has been entered is valid |
|
2516 |
+ var videoConfExten = $("#Video_Conf_Extension").val(); |
|
2517 |
+ if (/^[a-zA-Z0-9\*\#]+$/.test(videoConfExten)) { var finVideoConfExten = videoConfExten; } else { |
|
2518 |
+ var finVideoConfExten = ''; alert("The extension that you entered in the 'Video Conference Extension' field is not a valid extension!");} |
|
2519 |
+ |
|
2520 |
+ localDB.setItem("VidConfExtension", finVideoConfExten); |
|
2521 |
+ |
|
2522 |
+ var videoConfWinWidth = $("#Video_Conf_Window_Width").val(); |
|
2523 |
+ if ((/^[0-9]+$/.test(videoConfWinWidth)) && Math.abs(videoConfWinWidth) <= 100) { var finVideoConfWinWidth = Math.abs(videoConfWinWidth); } else { |
|
2524 |
+ var finVideoConfWinWidth = ''; alert("The percent value that you entered in the 'Percent of screen width ...' field is not valid!"); } |
|
2525 |
+ |
|
2526 |
+ localDB.setItem("VidConfWindowWidth", finVideoConfWinWidth); |
|
2527 |
+ |
|
2528 |
+ localDB.setItem("Notifications", ($("#Settings_Notifications").is(":checked"))? "1" : "0"); |
|
2529 |
+ |
|
2530 |
+ if ($("#emailIntegration").is(":checked")) { |
|
2531 |
+ |
|
2532 |
+ if (/^[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test($("#RoundcubeDomain").val())) {} else { |
|
2533 |
+ $("#emailIntegration").prop("checked", false); |
|
2534 |
+ $("#RoundcubeDomain").val(""); |
|
2535 |
+ alert("The Roundcube domain is not valid. After entering a valid Roundcube domain, please remember to check the checkbox 'Enable Roundcube email integration' again !"); |
|
2536 |
+ return; |
|
2537 |
+ } |
|
2538 |
+ |
|
2539 |
+ if (/^[A-Za-z0-9\_\.\-\@\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]{1,300}$/.test($("#RoundcubeUser").val())) {} else { |
|
2540 |
+ $("#emailIntegration").prop("checked", false); |
|
2541 |
+ $("#RoundcubeUser").val(""); |
|
2542 |
+ alert("The Roundcube user is not valid. After entering a valid Roundcube user, please remember to check the checkbox 'Enable Roundcube email integration' again !"); |
|
2543 |
+ return; |
|
2544 |
+ } |
|
2545 |
+ |
|
2546 |
+ if ($("#RoundcubePass").val() == '' || $("#RoundcubePass").val().length > 300) { |
|
2547 |
+ $("#emailIntegration").prop("checked", false); |
|
2548 |
+ $("#RoundcubePass").val(""); |
|
2549 |
+ alert("The Roundcube password is not valid. After entering a valid Roundcube password, please remember to check the checkbox 'Enable Roundcube email integration' again !"); |
|
2550 |
+ return; |
|
2551 |
+ } |
|
2552 |
+ |
|
2553 |
+ if ($("#rcBasicAuthUser").val().length > 300) { $("#rcBasicAuthUser").val(""); alert("The Roundcube basic authentication user is not valid."); return; } |
|
2554 |
+ |
|
2555 |
+ if ($("#rcBasicAuthPass").val().length > 300) { $("#rcBasicAuthPass").val(""); alert("The Roundcube basic authentication password is not valid."); return; } |
|
2556 |
+ } |
|
2557 |
+ |
|
2558 |
+ // The profile picture can't be saved if the style of its section is 'display: none;' |
|
2559 |
+ $("#AppearanceHtml").css({ 'display' : 'block', 'visibility' : 'hidden', 'margin-top' : '-228px' }); |
|
2560 |
+ |
|
2561 |
+ |
|
2562 |
+ // Convert the profile picture to base64 |
|
2563 |
+ $("#ImageCanvas").croppie('result', { |
|
2564 |
+ type: 'base64', |
|
2565 |
+ size: 'viewport', |
|
2566 |
+ format: 'png', |
|
2567 |
+ quality: 1, |
|
2568 |
+ circle: false |
|
2569 |
+ }).then(function(base64) { |
|
2570 |
+ localDB.setItem("profilePicture", base64); |
|
2571 |
+ }); |
|
2572 |
+ |
|
2573 |
+ setTimeout(function() { |
|
2574 |
+ saveConfToSqldb(); |
|
2575 |
+ }, 600); |
|
2576 |
+ |
|
2577 |
+ }); |
|
2578 |
+ |
|
2579 |
+ $("#closeImg").click(function() { $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); closeVideoAudio(); $.jeegoopopup.close(); }); |
|
2580 |
+ $("#cancel_button_conf").click(function() { $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); closeVideoAudio(); $.jeegoopopup.close(); }); |
|
2581 |
+ $("#jg_popup_overlay").click(function() { $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); closeVideoAudio(); $.jeegoopopup.close(); }); |
|
2582 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); closeVideoAudio(); $.jeegoopopup.close(); } }); |
|
2583 |
+ |
|
2584 |
+} |
|
2585 |
+ |
|
2586 |
+function checkNotificationPromise() { |
|
2587 |
+ try { |
|
2588 |
+ Notification.requestPermission().then(); |
|
2589 |
+ } |
|
2590 |
+ catch(e) { |
|
2591 |
+ return false; |
|
2592 |
+ } |
|
2593 |
+ return true; |
|
2594 |
+} |
|
2595 |
+function HandleNotifyPermission(p){ |
|
2596 |
+ |
|
2597 |
+ if(p == "granted") { |
|
2598 |
+ // Good |
|
2599 |
+ } else { |
|
2600 |
+ Alert(lang.alert_notification_permission, lang.permission, function(){ |
|
2601 |
+ console.log("Attempting to uncheck the checkbox..."); |
|
2602 |
+ $("#Settings_Notifications").prop("checked", false); |
|
2603 |
+ }); |
|
2604 |
+ } |
|
2605 |
+} |
|
2606 |
+function EditBuddyWindow(buddy){ |
|
2607 |
+ |
|
2608 |
+ $.jeegoopopup.close(); |
|
2609 |
+ |
|
2610 |
+ var buddyObj = null; |
|
2611 |
+ var itemId = -1; |
|
2612 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
2613 |
+ $.each(json.DataCollection, function (i, item) { |
|
2614 |
+ if(item.uID == buddy || item.cID == buddy || item.gID == buddy){ |
|
2615 |
+ buddyObj = item; |
|
2616 |
+ itemId = i; |
|
2617 |
+ return false; |
|
2618 |
+ } |
|
2619 |
+ }); |
|
2620 |
+ |
|
2621 |
+ if(buddyObj == null){ |
|
2622 |
+ Alert(lang.alert_not_found, lang.error); |
|
2623 |
+ return; |
|
2624 |
+ } |
|
2625 |
+ |
|
2626 |
+ var html = "<div id='EditContact'>"; |
|
2627 |
+ |
|
2628 |
+ html += "<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>"; |
|
2629 |
+ |
|
2630 |
+ html += "<div class='UiWindowField scroller'>"; |
|
2631 |
+ |
|
2632 |
+ html += "<div id=ImageCanvas style=\"width:150px; height:150px\"></div>"; |
|
2633 |
+ html += "<label for=ebFileUploader class=customBrowseButton style=\"margin-left: 200px; margin-top: -9px;\">Select File</label>"; |
|
2634 |
+ html += "<div><input type=file id=ebFileUploader /></div>"; |
|
2635 |
+ html += "<div style=\"margin-top: 50px\"></div>"; |
|
2636 |
+ |
|
2637 |
+ html += "<div class=UiText>"+ lang.display_name +":</div>"; |
|
2638 |
+ |
|
2639 |
+ html += "<div><input id=AddSomeone_Name class=UiInputText type=text placeholder='"+ lang.eg_display_name +"' value='"+ ((buddyObj.DisplayName && buddyObj.DisplayName != "null" && buddyObj.DisplayName != "undefined")? buddyObj.DisplayName : "") +"'></div>"; |
|
2640 |
+ |
|
2641 |
+ html += "<div class=UiText>"+ lang.title_description +":</div>"; |
|
2642 |
+ |
|
2643 |
+ if(buddyObj.Type == "extension"){ |
|
2644 |
+ html += "<div><input id=AddSomeone_Desc class=UiInputText type=text placeholder='"+ lang.eg_general_manager +"' value='"+ ((buddyObj.Position && buddyObj.Position != "null" && buddyObj.Position != "undefined")? buddyObj.Position : "") +"'></div>"; |
|
2645 |
+ } |
|
2646 |
+ else { |
|
2647 |
+ html += "<div><input id=AddSomeone_Desc class=UiInputText type=text placeholder='"+ lang.eg_general_manager +"' value='"+ ((buddyObj.Description && buddyObj.Description != "null" && buddyObj.Description != "undefined")? buddyObj.Description : "") +"'></div>"; |
|
2648 |
+ } |
|
2649 |
+ |
|
2650 |
+ html += "<div class=UiText>"+ lang.internal_subscribe_extension +":</div>"; |
|
2651 |
+ html += "<div><input id=AddSomeone_Exten class=UiInputText type=text placeholder='"+ lang.eg_internal_subscribe_extension +"' value='"+ ((buddyObj.ExtensionNumber && buddyObj.ExtensionNumber != "null" && buddyObj.ExtensionNumber != "undefined")? buddyObj.ExtensionNumber : "") +"'></div>"; |
|
2652 |
+ |
|
2653 |
+ html += "<div class=UiText>"+ lang.mobile_number +":</div>"; |
|
2654 |
+ html += "<div><input id=AddSomeone_Mobile class=UiInputText type=text placeholder='"+ lang.eg_mobile_number +"' value='"+ ((buddyObj.MobileNumber && buddyObj.MobileNumber != "null" && buddyObj.MobileNumber != "undefined")? buddyObj.MobileNumber : "") +"'></div>"; |
|
2655 |
+ |
|
2656 |
+ html += "<div class=UiText>"+ lang.contact_number_1 +":</div>"; |
|
2657 |
+ html += "<div><input id=AddSomeone_Num1 class=UiInputText type=text placeholder='"+ lang.eg_contact_number_1 +"' value='"+((buddyObj.ContactNumber1 && buddyObj.ContactNumber1 != "null" && buddyObj.ContactNumber1 != "undefined")? buddyObj.ContactNumber1 : "") +"'></div>"; |
|
2658 |
+ |
|
2659 |
+ html += "<div class=UiText>"+ lang.contact_number_2 +":</div>"; |
|
2660 |
+ html += "<div><input id=AddSomeone_Num2 class=UiInputText type=text placeholder='"+ lang.eg_contact_number_2 +"' value='"+ ((buddyObj.ContactNumber2 && buddyObj.ContactNumber2 != "null" && buddyObj.ContactNumber2 != "undefined")? buddyObj.ContactNumber2 : "") +"'></div>"; |
|
2661 |
+ |
|
2662 |
+ html += "<div class=UiText>"+ lang.email +":</div>"; |
|
2663 |
+ html += "<div><input id=AddSomeone_Email class=UiInputText type=text placeholder='"+ lang.email +"' value='"+ ((buddyObj.Email && buddyObj.Email != "null" && buddyObj.Email != "undefined")? buddyObj.Email : "") +"'></div>"; |
|
2664 |
+ |
|
2665 |
+ html += "</div></div>" |
|
2666 |
+ |
|
2667 |
+ $.jeegoopopup.open({ |
|
2668 |
+ title: 'Edit Contact', |
|
2669 |
+ html: html, |
|
2670 |
+ width: '640', |
|
2671 |
+ height: '500', |
|
2672 |
+ center: true, |
|
2673 |
+ scrolling: 'no', |
|
2674 |
+ skinClass: 'jg_popup_basic', |
|
2675 |
+ contentClass: 'editContactPopup', |
|
2676 |
+ overlay: true, |
|
2677 |
+ opacity: 50, |
|
2678 |
+ draggable: true, |
|
2679 |
+ resizable: false, |
|
2680 |
+ fadeIn: 0 |
|
2681 |
+ }); |
|
2682 |
+ |
|
2683 |
+ $("#jg_popup_b").append("<div id=bottomButtons><button id=save_button>Save</button><button id=cancel_button>Cancel</button></div>"); |
|
2684 |
+ |
|
2685 |
+ |
|
2686 |
+ var contactDatabaseId = ''; |
|
2687 |
+ |
|
2688 |
+ $.ajax({ |
|
2689 |
+ type: "POST", |
|
2690 |
+ url: "get-contact-dbid.php", |
|
2691 |
+ dataType: "JSON", |
|
2692 |
+ data: { |
|
2693 |
+ username: userName, |
|
2694 |
+ contact_name: buddyObj.DisplayName, |
|
2695 |
+ s_ajax_call: validateSToken |
|
2696 |
+ }, |
|
2697 |
+ success: function(response) { |
|
2698 |
+ if (response.successorfailure == 'success') { |
|
2699 |
+ contactDatabaseId = response.cntctDatabaseID; |
|
2700 |
+ } else { alert("Error while attempting to retrieve contact data from the database!"); } |
|
2701 |
+ }, |
|
2702 |
+ error: function(response) { |
|
2703 |
+ alert("Error while attempting to retrieve contact data from the database!"); |
|
2704 |
+ } |
|
2705 |
+ }); |
|
2706 |
+ |
|
2707 |
+ // DoOnLoad |
|
2708 |
+ var cropper = $("#ImageCanvas").croppie({ |
|
2709 |
+ viewport: { width: 150, height: 150, type: 'circle' } |
|
2710 |
+ }); |
|
2711 |
+ |
|
2712 |
+ // Preview Existing Image |
|
2713 |
+ if(buddyObj.Type == "extension"){ |
|
2714 |
+ $("#ImageCanvas").croppie('bind', { url: getPicture(buddyObj.uID, "extension") }).then(function() { |
|
2715 |
+ $('.cr-slider').attr({ min: 0.5, max: 3 }); |
|
2716 |
+ }); |
|
2717 |
+ } else if(buddyObj.Type == "contact") { |
|
2718 |
+ $("#ImageCanvas").croppie('bind', { url: getPicture(buddyObj.cID, "contact") }).then(function() { |
|
2719 |
+ $('.cr-slider').attr({ min: 0.5, max: 3 }); |
|
2720 |
+ }); |
|
2721 |
+ } else if(buddyObj.Type == "group") { |
|
2722 |
+ $("#ImageCanvas").croppie('bind', { url: getPicture(buddyObj.gID, "group") }).then(function() { |
|
2723 |
+ $('.cr-slider').attr({ min: 0.5, max: 3 }); |
|
2724 |
+ }); |
|
2725 |
+ } |
|
2726 |
+ |
|
2727 |
+ // Wireup File Change |
|
2728 |
+ $("#ebFileUploader").change(function () { |
|
2729 |
+ |
|
2730 |
+ var filesArray = $(this).prop('files'); |
|
2731 |
+ |
|
2732 |
+ if (filesArray.length == 1) { |
|
2733 |
+ var uploadId = Math.floor(Math.random() * 1000000000); |
|
2734 |
+ var fileObj = filesArray[0]; |
|
2735 |
+ var fileName = fileObj.name; |
|
2736 |
+ var fileSize = fileObj.size; |
|
2737 |
+ |
|
2738 |
+ if (fileSize <= 52428800) { |
|
2739 |
+ console.log("Adding (" + uploadId + "): " + fileName + " of size: " + fileSize + "bytes"); |
|
2740 |
+ |
|
2741 |
+ var reader = new FileReader(); |
|
2742 |
+ reader.Name = fileName; |
|
2743 |
+ reader.UploadId = uploadId; |
|
2744 |
+ reader.Size = fileSize; |
|
2745 |
+ reader.onload = function (event) { |
|
2746 |
+ $("#ImageCanvas").croppie('bind', { |
|
2747 |
+ url: event.target.result |
|
2748 |
+ }); |
|
2749 |
+ } |
|
2750 |
+ reader.readAsDataURL(fileObj); |
|
2751 |
+ } else { |
|
2752 |
+ Alert(lang.alert_file_size, lang.error); |
|
2753 |
+ } |
|
2754 |
+ } else { |
|
2755 |
+ Alert(lang.alert_single_file, lang.error); |
|
2756 |
+ } |
|
2757 |
+ }); |
|
2758 |
+ |
|
2759 |
+ $("#save_button").click(function() { |
|
2760 |
+ |
|
2761 |
+ var currentCtctName = $("#AddSomeone_Name").val(); |
|
2762 |
+ |
|
2763 |
+ if (currentCtctName != null && currentCtctName.trim() !== '') { |
|
2764 |
+ |
|
2765 |
+ if (/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(currentCtctName)) { |
|
2766 |
+ |
|
2767 |
+ buddyObj.LastActivity = utcDateNow(); |
|
2768 |
+ buddyObj.DisplayName = currentCtctName; |
|
2769 |
+ |
|
2770 |
+ var currentDesc = $("#AddSomeone_Desc").val(); |
|
2771 |
+ if (currentDesc != null && currentDesc.trim() !== '') { |
|
2772 |
+ if (/^[A-Za-z0-9\s\-\.\'\"\[\]\(\)\{\}\_\!\?\~\@\%\^\&\*\+\>\<\;\:\=]+$/.test(currentDesc)) { var finCurrentDesc = currentDesc; } else { |
|
2773 |
+ var finCurrentDesc = ''; alert('The title/description that you entered is not valid!'); } |
|
2774 |
+ } else { var finCurrentDesc = ''; } |
|
2775 |
+ |
|
2776 |
+ if(buddyObj.Type == "extension") { |
|
2777 |
+ buddyObj.Position = finCurrentDesc; |
|
2778 |
+ |
|
2779 |
+ } else { |
|
2780 |
+ buddyObj.Description = finCurrentDesc; |
|
2781 |
+ } |
|
2782 |
+ |
|
2783 |
+ var currentExtension = $("#AddSomeone_Exten").val(); |
|
2784 |
+ if (currentExtension != null && currentExtension.trim() !== '') { |
|
2785 |
+ if (/^[a-zA-Z0-9\*\#]+$/.test(currentExtension)) { var finCurrentExtension = currentExtension; } else { |
|
2786 |
+ var finCurrentExtension = ''; alert("The extension that you entered in the 'Extension (Internal)' field is not a valid extension!"); } |
|
2787 |
+ } else { var finCurrentExtension = ''; } |
|
2788 |
+ |
|
2789 |
+ buddyObj.ExtensionNumber = finCurrentExtension; |
|
2790 |
+ |
|
2791 |
+ var currentMobile = $("#AddSomeone_Mobile").val(); |
|
2792 |
+ if (currentMobile != null && currentMobile.trim() !== '') { |
|
2793 |
+ if (/^[0-9\s\+\#]+$/.test(currentMobile)) { var finCurrentMobile = currentMobile; } else { |
|
2794 |
+ var finCurrentMobile = ''; alert("The phone number that you entered in the 'Mobile Number' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); } |
|
2795 |
+ } else { var finCurrentMobile = ''; } |
|
2796 |
+ |
|
2797 |
+ buddyObj.MobileNumber = finCurrentMobile; |
|
2798 |
+ |
|
2799 |
+ var currentNum1 = $("#AddSomeone_Num1").val(); |
|
2800 |
+ if (currentNum1 != null && currentNum1.trim() !== '') { |
|
2801 |
+ if (/^[0-9\s\+\#]+$/.test(currentNum1)) { var finCurrentNum1 = currentNum1; } else { |
|
2802 |
+ var finCurrentNum1 = ''; alert("The phone number that you entered in the 'Contact Number 1' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); } |
|
2803 |
+ } else { var finCurrentNum1 = ''; } |
|
2804 |
+ |
|
2805 |
+ buddyObj.ContactNumber1 = finCurrentNum1; |
|
2806 |
+ |
|
2807 |
+ var currentNum2 = $("#AddSomeone_Num2").val(); |
|
2808 |
+ if (currentNum2 != null && currentNum2.trim() !== '') { |
|
2809 |
+ if (/^[0-9\s\+\#]+$/.test(currentNum2)) { var finCurrentNum2 = currentNum2; } else { |
|
2810 |
+ var finCurrentNum2 = ''; alert("The phone number that you entered in the 'Contact Number 2' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); } |
|
2811 |
+ } else { var finCurrentNum2 = ''; } |
|
2812 |
+ |
|
2813 |
+ buddyObj.ContactNumber2 = finCurrentNum2; |
|
2814 |
+ |
|
2815 |
+ var currentEmail = $("#AddSomeone_Email").val(); |
|
2816 |
+ if (currentEmail != null && currentEmail.trim() !== '') { |
|
2817 |
+ if (/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(currentEmail)) { var finCurrentEmail = currentEmail; } else { |
|
2818 |
+ var finCurrentEmail = ''; alert("The email that you entered is not a valid email address!"); } |
|
2819 |
+ } else { var finCurrentEmail = ''; } |
|
2820 |
+ |
|
2821 |
+ buddyObj.Email = finCurrentEmail; |
|
2822 |
+ |
|
2823 |
+ |
|
2824 |
+ // Update Image |
|
2825 |
+ var constraints = { |
|
2826 |
+ type: 'base64', |
|
2827 |
+ size: 'viewport', |
|
2828 |
+ format: 'png', |
|
2829 |
+ quality: 1, |
|
2830 |
+ circle: false |
|
2831 |
+ } |
|
2832 |
+ |
|
2833 |
+ $("#ImageCanvas").croppie('result', constraints).then(function(base64) { |
|
2834 |
+ if(buddyObj.Type == "extension"){ |
|
2835 |
+ localDB.setItem("img-"+ buddyObj.uID +"-extension", base64); |
|
2836 |
+ $("#contact-"+ buddyObj.uID +"-picture-main").css("background-image", 'url('+ getPicture(buddyObj.uID, 'extension') +')'); |
|
2837 |
+ $("#contact-"+ buddyObj.uID +"-presence-main").html(buddyObj.Position); |
|
2838 |
+ |
|
2839 |
+ // Save contact picture to SQL database |
|
2840 |
+ var newPic = []; |
|
2841 |
+ newPic = [buddyObj.DisplayName, localDB.getItem("img-"+ buddyObj.uID +"-extension", base64)]; |
|
2842 |
+ saveContactPicToSQLDB(newPic); |
|
2843 |
+ } |
|
2844 |
+ else if(buddyObj.Type == "contact") { |
|
2845 |
+ localDB.setItem("img-"+ buddyObj.cID +"-contact", base64); |
|
2846 |
+ $("#contact-"+ buddyObj.cID +"-picture-main").css("background-image", 'url('+ getPicture(buddyObj.cID, 'contact') +')'); |
|
2847 |
+ $("#contact-"+ buddyObj.cID +"-presence-main").html(buddyObj.Description); |
|
2848 |
+ |
|
2849 |
+ // Save contact picture to SQL database |
|
2850 |
+ var newPic = []; |
|
2851 |
+ newPic = [buddyObj.DisplayName, localDB.getItem("img-"+ buddyObj.cID +"-contact", base64)]; |
|
2852 |
+ saveContactPicToSQLDB(newPic); |
|
2853 |
+ } |
|
2854 |
+ else if(buddyObj.Type == "group") { |
|
2855 |
+ localDB.setItem("img-"+ buddyObj.gID +"-group", base64); |
|
2856 |
+ $("#contact-"+ buddyObj.gID +"-picture-main").css("background-image", 'url('+ getPicture(buddyObj.gID, 'group') +')'); |
|
2857 |
+ $("#contact-"+ buddyObj.gID +"-presence-main").html(buddyObj.Description); |
|
2858 |
+ |
|
2859 |
+ // Save contact picture to SQL database |
|
2860 |
+ var newPic = []; |
|
2861 |
+ newPic = [buddyObj.DisplayName, localDB.getItem("img-"+ buddyObj.gID +"-group", base64)]; |
|
2862 |
+ saveContactPicToSQLDB(newPic); |
|
2863 |
+ } |
|
2864 |
+ |
|
2865 |
+ // Update |
|
2866 |
+ UpdateBuddyList(); |
|
2867 |
+ }); |
|
2868 |
+ |
|
2869 |
+ // Update: |
|
2870 |
+ json.DataCollection[itemId] = buddyObj; |
|
2871 |
+ |
|
2872 |
+ // Save To DB |
|
2873 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
2874 |
+ |
|
2875 |
+ var newPerson = []; |
|
2876 |
+ |
|
2877 |
+ newPerson = [currentCtctName, finCurrentDesc, finCurrentExtension, finCurrentMobile, finCurrentNum1, finCurrentNum2, finCurrentEmail, contactDatabaseId]; |
|
2878 |
+ |
|
2879 |
+ updateContactToSQLDB(newPerson); |
|
2880 |
+ |
|
2881 |
+ // Update the Memory Array, so that the UpdateBuddyList can make the changes |
|
2882 |
+ for(var b = 0; b < Buddies.length; b++) { |
|
2883 |
+ if(buddyObj.Type == "extension"){ |
|
2884 |
+ if(buddyObj.uID == Buddies[b].identity){ |
|
2885 |
+ Buddies[b].lastActivity = buddyObj.LastActivity; |
|
2886 |
+ Buddies[b].CallerIDName = buddyObj.DisplayName; |
|
2887 |
+ Buddies[b].Desc = buddyObj.Position; |
|
2888 |
+ } |
|
2889 |
+ } |
|
2890 |
+ else if(buddyObj.Type == "contact") { |
|
2891 |
+ if(buddyObj.cID == Buddies[b].identity){ |
|
2892 |
+ Buddies[b].lastActivity = buddyObj.LastActivity; |
|
2893 |
+ Buddies[b].CallerIDName = buddyObj.DisplayName; |
|
2894 |
+ Buddies[b].Desc = buddyObj.Description; |
|
2895 |
+ } |
|
2896 |
+ } |
|
2897 |
+ else if(buddyObj.Type == "group") { |
|
2898 |
+ |
|
2899 |
+ } |
|
2900 |
+ } |
|
2901 |
+ |
|
2902 |
+ UpdateBuddyList(); |
|
2903 |
+ |
|
2904 |
+ $.jeegoopopup.close(); |
|
2905 |
+ $("#jg_popup_b").empty(); |
|
2906 |
+ |
|
2907 |
+ } else { alert('The display name that you entered is not a valid display name!'); } |
|
2908 |
+ |
|
2909 |
+ } else { alert("'Display Name' cannot be empty!"); } |
|
2910 |
+ |
|
2911 |
+ }); |
|
2912 |
+ |
|
2913 |
+ var maxWidth = $(window).width() - 16; |
|
2914 |
+ var maxHeight = $(window).height() - 110; |
|
2915 |
+ |
|
2916 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
2917 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
2918 |
+ $.jeegoopopup.center(); |
|
2919 |
+ $("#maximizeImg").hide(); |
|
2920 |
+ $("#minimizeImg").hide(); |
|
2921 |
+ } else { |
|
2922 |
+ $.jeegoopopup.width(640).height(500); |
|
2923 |
+ $.jeegoopopup.center(); |
|
2924 |
+ $("#minimizeImg").hide(); |
|
2925 |
+ $("#maximizeImg").show(); |
|
2926 |
+ } |
|
2927 |
+ |
|
2928 |
+ $(window).resize(function() { |
|
2929 |
+ maxWidth = $(window).width() - 16; |
|
2930 |
+ maxHeight = $(window).height() - 110; |
|
2931 |
+ $.jeegoopopup.center(); |
|
2932 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
2933 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
2934 |
+ $.jeegoopopup.center(); |
|
2935 |
+ $("#maximizeImg").hide(); |
|
2936 |
+ $("#minimizeImg").hide(); |
|
2937 |
+ } else { |
|
2938 |
+ $.jeegoopopup.width(640).height(500); |
|
2939 |
+ $.jeegoopopup.center(); |
|
2940 |
+ $("#minimizeImg").hide(); |
|
2941 |
+ $("#maximizeImg").show(); |
|
2942 |
+ } |
|
2943 |
+ }); |
|
2944 |
+ |
|
2945 |
+ $("#minimizeImg").click(function() { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); }); |
|
2946 |
+ $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); }); |
|
2947 |
+ |
|
2948 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
2949 |
+ $("#cancel_button").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
2950 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
2951 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); |
|
2952 |
+} |
|
2953 |
+ |
|
2954 |
+// Document Ready |
|
2955 |
+// ============== |
|
2956 |
+$(document).ready(function () { |
|
2957 |
+ |
|
2958 |
+ // Load Langauge File |
|
2959 |
+ // ================== |
|
2960 |
+ $.getJSON(hostingPrefex + "lang/en.json", function (data){ |
|
2961 |
+ lang = data; |
|
2962 |
+ var userLang = GetAlternateLanguage(); |
|
2963 |
+ if(userLang != ""){ |
|
2964 |
+ $.getJSON(hostingPrefex +"lang/"+ userLang +".json", function (altdata){ |
|
2965 |
+ lang = altdata; |
|
2966 |
+ }).always(function() { |
|
2967 |
+ console.log("Alternate Lanaguage Pack loaded: ", lang); |
|
2968 |
+ InitUi(); |
|
2969 |
+ }); |
|
2970 |
+ } |
|
2971 |
+ else { |
|
2972 |
+ console.log("Lanaguage Pack already loaded: ", lang); |
|
2973 |
+ InitUi(); |
|
2974 |
+ } |
|
2975 |
+ }); |
|
2976 |
+ |
|
2977 |
+ // Get configuration data from SQL database |
|
2978 |
+ getConfFromSqldb(); |
|
2979 |
+ getExternalUserConfFromSqldb(); |
|
2980 |
+}); |
|
2981 |
+ |
|
2982 |
+// Init UI |
|
2983 |
+// ======= |
|
2984 |
+function InitUi(){ |
|
2985 |
+ |
|
2986 |
+ var phone = $("#Phone"); |
|
2987 |
+ phone.empty(); |
|
2988 |
+ phone.attr("class", "pageContainer"); |
|
2989 |
+ |
|
2990 |
+ // Left Section |
|
2991 |
+ var leftSection = $("<div>"); |
|
2992 |
+ leftSection.attr("id", "leftContent"); |
|
2993 |
+ leftSection.attr("style", "float:left; height: 100%; width:320px"); |
|
2994 |
+ |
|
2995 |
+ var leftHTML = "<table style=\"height:100%; width:100%\" cellspacing=5 cellpadding=0>"; |
|
2996 |
+ leftHTML += "<tr><td class=logoSection style=\"height: 50px\"><div id=\"smallLogo\"><img src=\"images/small-logo.svg\" /></div><div id=\"inLogoSection\"><div id=\"emailInLogoSection\" onclick=\"ShowEmailWindow()\" title=\"Email\"><i class=\"fa fa-envelope-o\" aria-hidden=\"true\"></i></div><div id=\"aboutInLogoSection\" onclick=\"ShowAboutWindow()\" title=\"About\"><button id=\"aboutImg\"></button></div><div id=\"shrinkLeftPanel\" onclick=\"CollapseLeftPanel()\" title=\"Collapse\"><button id=\"collapseLeftPanel\"></button></div></div></td></tr>"; |
|
2997 |
+ leftHTML += "<tr><td class=streamSection style=\"height: 82px\">"; |
|
2998 |
+ |
|
2999 |
+ // Profile User |
|
3000 |
+ leftHTML += "<div class=profileContainer>"; |
|
3001 |
+ leftHTML += "<div class=contact id=UserProfile style=\"margin-bottom:12px;\">"; |
|
3002 |
+ leftHTML += "<div id=UserProfilePic class=buddyIcon title=\"Status\"></div>"; |
|
3003 |
+ leftHTML += "<span id=reglink class=dotOffline></span>"; |
|
3004 |
+ leftHTML += "<span id=dereglink class=dotOnline style=\"display:none\"><i class=\"fa fa-wifi\" style=\"line-height: 14px; text-align: center; display: block;\"></i></span>"; |
|
3005 |
+ leftHTML += "<span id=WebRtcFailed class=dotFailed style=\"display:none\"><i class=\"fa fa-cross\" style=\"line-height: 14px; text-align: center; display: block;\"></i></span>"; |
|
3006 |
+ leftHTML += "<div class=contactNameText style=\"margin-right: 0px;\"><i class=\"fa fa-phone-square\"></i> <span id=UserDID></span> - <span id=UserCallID></span></div>"; |
|
3007 |
+ leftHTML += "<div id=regStatus class=presenceText> </div>"; |
|
3008 |
+ leftHTML += "</div>"; |
|
3009 |
+ // Search / Add Buddies |
|
3010 |
+ leftHTML += "<div id=searchBoxAndIcons>"; |
|
3011 |
+ leftHTML += "<span class=searchClean><INPUT id=txtFindBuddy type=text autocomplete=none style=\"width:142px;\" title=\"Find Contact\"></span>"; |
|
3012 |
+ leftHTML += "<div id=ButtonsOnSearchLine>"; |
|
3013 |
+ leftHTML += "<button id=BtnFreeDial title='"+ lang.dial_number +"'></button>"; |
|
3014 |
+ leftHTML += "<button id=LaunchVideoConf title='"+ lang.launch_video_conference +"'><i class=\"fa fa-users\"></i></button>"; |
|
3015 |
+ leftHTML += "<button id=BtnSettings title='"+ lang.account_settings +"'><i class=\"fa fa-cog\"></i></button>"; |
|
3016 |
+ leftHTML += "</div>"; |
|
3017 |
+ leftHTML += "</div>"; |
|
3018 |
+ leftHTML += "</div>"; |
|
3019 |
+ leftHTML += "</td></tr>"; |
|
3020 |
+ // Lines & Buddies |
|
3021 |
+ leftHTML += "<tr><td class=streamSection><div id=myContacts class=\"contactArea cleanScroller\"></div></td></tr>"; |
|
3022 |
+ leftHTML += "</table>"; |
|
3023 |
+ |
|
3024 |
+ leftSection.html(leftHTML); |
|
3025 |
+ |
|
3026 |
+ // Right Section |
|
3027 |
+ var rightSection = $("<div>"); |
|
3028 |
+ rightSection.attr("id", "rightContent"); |
|
3029 |
+ rightSection.attr("style", "margin-left: 320px; height: 100%; overflow: auto;"); |
|
3030 |
+ |
|
3031 |
+ phone.append(leftSection); |
|
3032 |
+ phone.append(rightSection); |
|
3033 |
+ |
|
3034 |
+ // Setup Windows |
|
3035 |
+ windowsCollection = ''; |
|
3036 |
+ messagingCollection = ''; |
|
3037 |
+ |
|
3038 |
+ if(DisableFreeDial == true) $("#BtnFreeDial").hide(); |
|
3039 |
+ if(DisableBuddies == true) $("#BtnAddSomeone").hide(); |
|
3040 |
+ if(enabledGroupServices == false) $("#BtnCreateGroup").hide(); |
|
3041 |
+ |
|
3042 |
+ $("#UserDID").html(profileUser); |
|
3043 |
+ $("#UserCallID").html(profileName); |
|
3044 |
+ $("#UserProfilePic").css("background-image", "url('"+ getPicture("profilePicture") +"')"); |
|
3045 |
+ |
|
3046 |
+ $("#txtFindBuddy").attr("placeholder", lang.find_someone); |
|
3047 |
+ $("#txtFindBuddy").on('keyup', function(event){ |
|
3048 |
+ UpdateBuddyList(); |
|
3049 |
+ }); |
|
3050 |
+ |
|
3051 |
+ $("#BtnFreeDial").on('click', function(event){ |
|
3052 |
+ ShowDial(this); |
|
3053 |
+ }); |
|
3054 |
+ |
|
3055 |
+ $("#BtnAddSomeone").attr("title", lang.add_contact); |
|
3056 |
+ $("#BtnAddSomeone").on('click', function(event){ |
|
3057 |
+ AddSomeoneWindow(); |
|
3058 |
+ }); |
|
3059 |
+ |
|
3060 |
+ $("#BtnCreateGroup").attr("title", lang.create_group); |
|
3061 |
+ $("#BtnCreateGroup").on('click', function(event){ |
|
3062 |
+ CreateGroupWindow(); |
|
3063 |
+ }); |
|
3064 |
+ |
|
3065 |
+ $("#LaunchVideoConf").on('click', function(event){ |
|
3066 |
+ ShowLaunchVidConfMenu(this); |
|
3067 |
+ }); |
|
3068 |
+ |
|
3069 |
+ $("#BtnSettings").on('click', function(event){ |
|
3070 |
+ ShowAccountSettingsMenu(this); |
|
3071 |
+ }); |
|
3072 |
+ |
|
3073 |
+ $("#UserProfile").on('click', function(event){ |
|
3074 |
+ ShowMyProfileMenu(this); |
|
3075 |
+ }); |
|
3076 |
+ |
|
3077 |
+ UpdateUI(); |
|
3078 |
+ |
|
3079 |
+ PopulateBuddyList(); |
|
3080 |
+ |
|
3081 |
+ // Select Last user |
|
3082 |
+ if(localDB.getItem("SelectedBuddy") != null){ |
|
3083 |
+ console.log("Selecting previously selected buddy...", localDB.getItem("SelectedBuddy")); |
|
3084 |
+ SelectBuddy(localDB.getItem("SelectedBuddy")); |
|
3085 |
+ UpdateUI(); |
|
3086 |
+ } |
|
3087 |
+ |
|
3088 |
+ PreloadAudioFiles(); |
|
3089 |
+ |
|
3090 |
+ CreateUserAgent(); |
|
3091 |
+ |
|
3092 |
+ getContactsFromSQLDB(); |
|
3093 |
+ |
|
3094 |
+ generateChatRSAKeys(getDbItem("SipUsername", "")); |
|
3095 |
+ |
|
3096 |
+ removeTextChatUploads(getDbItem("SipUsername", "")); |
|
3097 |
+} |
|
3098 |
+ |
|
3099 |
+function PreloadAudioFiles(){ |
|
3100 |
+ audioBlobs.Alert = { file : "Alert.mp3", url : hostingPrefex +"sounds/Alert.mp3" } |
|
3101 |
+ audioBlobs.Ringtone = { file : "Ringtone_1.mp3", url : hostingPrefex +"sounds/Ringtone_1.mp3" } |
|
3102 |
+ audioBlobs.speaker_test = { file : "Speaker_test.mp3", url : hostingPrefex +"sounds/Speaker_test.mp3" } |
|
3103 |
+ audioBlobs.Busy_UK = { file : "Tone_Busy-UK.mp3", url : hostingPrefex +"sounds/Tone_Busy-UK.mp3" } |
|
3104 |
+ audioBlobs.Busy_US = { file : "Tone_Busy-US.mp3", url : hostingPrefex +"sounds/Tone_Busy-US.mp3" } |
|
3105 |
+ audioBlobs.CallWaiting = { file : "Tone_CallWaiting.mp3", url : hostingPrefex +"sounds/Tone_CallWaiting.mp3" } |
|
3106 |
+ audioBlobs.Congestion_UK = { file : "Tone_Congestion-UK.mp3", url : hostingPrefex +"sounds/Tone_Congestion-UK.mp3" } |
|
3107 |
+ audioBlobs.Congestion_US = { file : "Tone_Congestion-US.mp3", url : hostingPrefex +"sounds/Tone_Congestion-US.mp3" } |
|
3108 |
+ audioBlobs.EarlyMedia_Australia = { file : "Tone_EarlyMedia-Australia.mp3", url : hostingPrefex +"sounds/Tone_EarlyMedia-Australia.mp3" } |
|
3109 |
+ audioBlobs.EarlyMedia_European = { file : "Tone_EarlyMedia-European.mp3", url : hostingPrefex +"sounds/Tone_EarlyMedia-European.mp3" } |
|
3110 |
+ audioBlobs.EarlyMedia_Japan = { file : "Tone_EarlyMedia-Japan.mp3", url : hostingPrefex +"sounds/Tone_EarlyMedia-Japan.mp3" } |
|
3111 |
+ audioBlobs.EarlyMedia_UK = { file : "Tone_EarlyMedia-UK.mp3", url : hostingPrefex +"sounds/Tone_EarlyMedia-UK.mp3" } |
|
3112 |
+ audioBlobs.EarlyMedia_US = { file : "Tone_EarlyMedia-US.mp3", url : hostingPrefex +"sounds/Tone_EarlyMedia-US.mp3" } |
|
3113 |
+ |
|
3114 |
+ $.each(audioBlobs, function (i, item) { |
|
3115 |
+ var oReq = new XMLHttpRequest(); |
|
3116 |
+ oReq.open("GET", item.url, true); |
|
3117 |
+ oReq.responseType = "blob"; |
|
3118 |
+ oReq.onload = function(oEvent) { |
|
3119 |
+ var reader = new FileReader(); |
|
3120 |
+ reader.readAsDataURL(oReq.response); |
|
3121 |
+ reader.onload = function() { |
|
3122 |
+ item.blob = reader.result; |
|
3123 |
+ } |
|
3124 |
+ } |
|
3125 |
+ oReq.send(); |
|
3126 |
+ }); |
|
3127 |
+} |
|
3128 |
+// Create User Agent |
|
3129 |
+// ================= |
|
3130 |
+function CreateUserAgent() { |
|
3131 |
+ |
|
3132 |
+ $.ajax({ |
|
3133 |
+ 'async': false, |
|
3134 |
+ 'global': false, |
|
3135 |
+ type: "POST", |
|
3136 |
+ url: "get-sippass.php", |
|
3137 |
+ dataType: "JSON", |
|
3138 |
+ data: { |
|
3139 |
+ username: userName, |
|
3140 |
+ s_ajax_call: validateSToken |
|
3141 |
+ }, |
|
3142 |
+ success: function (sipdatafromdb) { |
|
3143 |
+ decSipPass = sipdatafromdb; |
|
3144 |
+ }, |
|
3145 |
+ error: function(sipdatafromdb) { |
|
3146 |
+ alert("An error occurred while attempting to retrieve data from the database!"); |
|
3147 |
+ } |
|
3148 |
+ }); |
|
3149 |
+ |
|
3150 |
+ try { |
|
3151 |
+ console.log("Creating User Agent..."); |
|
3152 |
+ var options = { |
|
3153 |
+ displayName: profileName, |
|
3154 |
+ uri: SipUsername + "@" + wssServer, |
|
3155 |
+ transportOptions: { |
|
3156 |
+ wsServers: "wss://" + wssServer + ":"+ WebSocketPort +""+ ServerPath, |
|
3157 |
+ traceSip: false, |
|
3158 |
+ connectionTimeout: TransportConnectionTimeout, |
|
3159 |
+ maxReconnectionAttempts: TransportReconnectionAttempts, |
|
3160 |
+ reconnectionTimeout: TransportReconnectionTimeout, |
|
3161 |
+ }, |
|
3162 |
+ sessionDescriptionHandlerFactoryOptions:{ |
|
3163 |
+ peerConnectionOptions :{ |
|
3164 |
+ alwaysAcquireMediaFirst: true, // Better for firefox, but seems to have no effect on others |
|
3165 |
+ iceCheckingTimeout: IceStunCheckTimeout, |
|
3166 |
+ rtcConfiguration: {} |
|
3167 |
+ } |
|
3168 |
+ }, |
|
3169 |
+ authorizationUser: SipUsername, |
|
3170 |
+// password: SipPassword, |
|
3171 |
+ password: decSipPass, |
|
3172 |
+ registerExpires: RegisterExpires, |
|
3173 |
+ hackWssInTransport: WssInTransport, |
|
3174 |
+ hackIpInContact: IpInContact, |
|
3175 |
+ userAgentString: userAgentStr, |
|
3176 |
+ autostart: false, |
|
3177 |
+ register: false, |
|
3178 |
+ } |
|
3179 |
+ |
|
3180 |
+ decSipPass = ''; |
|
3181 |
+ |
|
3182 |
+ var currentStunServer = getDbItem("StunServer", ""); |
|
3183 |
+ |
|
3184 |
+ if (currentStunServer == '' || currentStunServer == null || typeof currentStunServer == 'undefined') { |
|
3185 |
+ var IceStunServersList = ''; |
|
3186 |
+ } else { var IceStunServersList = '[{"urls":"stun:'+currentStunServer+'"}]'; } |
|
3187 |
+ |
|
3188 |
+ if (IceStunServersList != "") { |
|
3189 |
+ options.sessionDescriptionHandlerFactoryOptions.peerConnectionOptions.rtcConfiguration.iceServers = JSON.parse(IceStunServersList); |
|
3190 |
+ } |
|
3191 |
+ |
|
3192 |
+ userAgent = new SIP.UA(options); |
|
3193 |
+ console.log("Creating User Agent... Done"); |
|
3194 |
+ } |
|
3195 |
+ catch (e) { |
|
3196 |
+ console.error("Error creating User Agent: "+ e); |
|
3197 |
+ $("#regStatus").html(lang.error_user_agant); |
|
3198 |
+ alert(e.message); |
|
3199 |
+ return; |
|
3200 |
+ } |
|
3201 |
+ |
|
3202 |
+ // UA Register events |
|
3203 |
+ userAgent.on('registered', function () { |
|
3204 |
+ // This code fires on re-regiter after session timeout |
|
3205 |
+ // to ensure that events are not fired multiple times |
|
3206 |
+ // an isReRegister state is kept. |
|
3207 |
+ if(!isReRegister) { |
|
3208 |
+ console.log("Registered!"); |
|
3209 |
+ |
|
3210 |
+ $("#reglink").hide(); |
|
3211 |
+ $("#dereglink").show(); |
|
3212 |
+ if(DoNotDisturbEnabled || DoNotDisturbPolicy == "enabled") { |
|
3213 |
+ $("#dereglink").attr("class", "dotDoNotDisturb"); |
|
3214 |
+ } |
|
3215 |
+ |
|
3216 |
+ // Start Subscribe Loop |
|
3217 |
+ SubscribeAll(); |
|
3218 |
+ |
|
3219 |
+ // Output to status |
|
3220 |
+ $("#regStatus").html(lang.registered); |
|
3221 |
+ |
|
3222 |
+ // Custom Web hook |
|
3223 |
+ if(typeof web_hook_on_register !== 'undefined') web_hook_on_register(userAgent); |
|
3224 |
+ } |
|
3225 |
+ isReRegister = true; |
|
3226 |
+ }); |
|
3227 |
+ |
|
3228 |
+ userAgent.on('registrationFailed', function (response, cause) { |
|
3229 |
+ console.log("Registration Failed: " + cause); |
|
3230 |
+ $("#regStatus").html(lang.registration_failed); |
|
3231 |
+ |
|
3232 |
+ $("#reglink").show(); |
|
3233 |
+ $("#dereglink").hide(); |
|
3234 |
+ |
|
3235 |
+ // We set this flag here so that the re-register attepts are fully completed. |
|
3236 |
+ isReRegister = false; |
|
3237 |
+ |
|
3238 |
+ // Custom Web hook |
|
3239 |
+ if(typeof web_hook_on_registrationFailed !== 'undefined') web_hook_on_registrationFailed(cause); |
|
3240 |
+ }); |
|
3241 |
+ userAgent.on('unregistered', function () { |
|
3242 |
+ console.log("Unregistered, bye!"); |
|
3243 |
+ $("#regStatus").html(lang.unregistered); |
|
3244 |
+ |
|
3245 |
+ $("#reglink").show(); |
|
3246 |
+ $("#dereglink").hide(); |
|
3247 |
+ |
|
3248 |
+ // Custom Web hook |
|
3249 |
+ if(typeof web_hook_on_unregistered !== 'undefined') web_hook_on_unregistered(); |
|
3250 |
+ }); |
|
3251 |
+ |
|
3252 |
+ // UA transport |
|
3253 |
+ userAgent.on('transportCreated', function (transport) { |
|
3254 |
+ console.log("Transport Object Created"); |
|
3255 |
+ |
|
3256 |
+ // Transport Events |
|
3257 |
+ transport.on('connected', function () { |
|
3258 |
+ console.log("Connected to Web Socket!"); |
|
3259 |
+ $("#regStatus").html(lang.connected_to_web_socket); |
|
3260 |
+ |
|
3261 |
+ $("#WebRtcFailed").hide(); |
|
3262 |
+ |
|
3263 |
+ window.setTimeout(function (){ |
|
3264 |
+ Register(); |
|
3265 |
+ }, 500); |
|
3266 |
+ |
|
3267 |
+ }); |
|
3268 |
+ transport.on('disconnected', function () { |
|
3269 |
+ console.log("Disconnected from Web Socket!"); |
|
3270 |
+ $("#regStatus").html(lang.disconnected_from_web_socket); |
|
3271 |
+ |
|
3272 |
+ // We set this flag here so that the re-register attepts are fully completed. |
|
3273 |
+ isReRegister = false; |
|
3274 |
+ }); |
|
3275 |
+ transport.on('transportError', function () { |
|
3276 |
+ console.log("Web Socket error!"); |
|
3277 |
+ $("#regStatus").html(lang.web_socket_error); |
|
3278 |
+ |
|
3279 |
+ $("#WebRtcFailed").show(); |
|
3280 |
+ |
|
3281 |
+ // Custom Web hook |
|
3282 |
+ if(typeof web_hook_on_transportError !== 'undefined') web_hook_on_transportError(transport, userAgent); |
|
3283 |
+ }); |
|
3284 |
+ }); |
|
3285 |
+ |
|
3286 |
+ // Inbound Calls |
|
3287 |
+ userAgent.on("invite", function (session) { |
|
3288 |
+ |
|
3289 |
+ ReceiveCall(session); |
|
3290 |
+ |
|
3291 |
+ // Show a system notification when the phone rings |
|
3292 |
+ if (getDbItem("Notifications", "") == 1) { |
|
3293 |
+ incomingCallNote(); |
|
3294 |
+ } |
|
3295 |
+ |
|
3296 |
+ changePageTitle(); |
|
3297 |
+ |
|
3298 |
+ // Custom Web hook |
|
3299 |
+ if(typeof web_hook_on_invite !== 'undefined') web_hook_on_invite(session); |
|
3300 |
+ }); |
|
3301 |
+ |
|
3302 |
+ // Inbound Text Message |
|
3303 |
+ userAgent.on('message', function (message) { |
|
3304 |
+ ReceiveMessage(message); |
|
3305 |
+ |
|
3306 |
+ // Custom Web hook |
|
3307 |
+ if(typeof web_hook_on_message !== 'undefined') web_hook_on_message(message); |
|
3308 |
+ }); |
|
3309 |
+ |
|
3310 |
+ // Start the WebService Connection loop |
|
3311 |
+ console.log("Connecting to Web Socket..."); |
|
3312 |
+ $("#regStatus").html(lang.connecting_to_web_socket); |
|
3313 |
+ userAgent.start(); |
|
3314 |
+ |
|
3315 |
+ // Register Buttons |
|
3316 |
+ $("#reglink").on('click', Register); |
|
3317 |
+ |
|
3318 |
+ // WebRTC Error Page |
|
3319 |
+ $("#WebRtcFailed").on('click', function(){ |
|
3320 |
+ Confirm(lang.error_connecting_web_socket, lang.web_socket_error, function(){ |
|
3321 |
+ window.open("https://"+ wssServer +":"+ WebSocketPort +"/httpstatus"); |
|
3322 |
+ }, null); |
|
3323 |
+ }); |
|
3324 |
+} |
|
3325 |
+ |
|
3326 |
+ |
|
3327 |
+// Registration |
|
3328 |
+// ============ |
|
3329 |
+function Register() { |
|
3330 |
+ |
|
3331 |
+ if (userAgent == null || userAgent.isRegistered()) return; |
|
3332 |
+ |
|
3333 |
+ console.log("Sending Registration..."); |
|
3334 |
+ $("#regStatus").html(lang.sending_registration); |
|
3335 |
+ userAgent.register(); |
|
3336 |
+ |
|
3337 |
+ if (getDbItem("Notifications", "") == 1) { |
|
3338 |
+ if (Notification.permission != "granted") { |
|
3339 |
+ Notification.requestPermission(); |
|
3340 |
+ } |
|
3341 |
+ } |
|
3342 |
+} |
|
3343 |
+function Unregister() { |
|
3344 |
+ if (userAgent == null || !userAgent.isRegistered()) return; |
|
3345 |
+ |
|
3346 |
+ console.log("Unsubscribing..."); |
|
3347 |
+ $("#regStatus").html(lang.unsubscribing); |
|
3348 |
+ try { |
|
3349 |
+ UnsubscribeAll(); |
|
3350 |
+ } catch (e) { } |
|
3351 |
+ |
|
3352 |
+ console.log("Disconnecting..."); |
|
3353 |
+ $("#regStatus").html(lang.disconnecting); |
|
3354 |
+ userAgent.unregister(); |
|
3355 |
+ |
|
3356 |
+ isReRegister = false; |
|
3357 |
+} |
|
3358 |
+ |
|
3359 |
+// Inbound Calls |
|
3360 |
+// ============= |
|
3361 |
+function ReceiveCall(session) { |
|
3362 |
+ var callerID = session.remoteIdentity.displayName; |
|
3363 |
+ var did = session.remoteIdentity.uri.user; |
|
3364 |
+ |
|
3365 |
+ if ( typeof callerID == 'undefined') { callerID = ""; } |
|
3366 |
+ |
|
3367 |
+ console.log("New Incoming Call!", callerID +" <"+ did +">"); |
|
3368 |
+ |
|
3369 |
+ var CurrentCalls = countSessions(session.id); |
|
3370 |
+ console.log("Current Call Count:", CurrentCalls); |
|
3371 |
+ |
|
3372 |
+ var buddyObj = FindBuddyByDid(did); |
|
3373 |
+ // Make new contact if it's not there |
|
3374 |
+ if(buddyObj == null) { |
|
3375 |
+ var buddyType = (did.length > DidLength)? "contact" : "extension"; |
|
3376 |
+ var focusOnBuddy = (CurrentCalls==0); |
|
3377 |
+ buddyObj = MakeBuddy(buddyType, true, focusOnBuddy, true, callerID, did); |
|
3378 |
+ } else { |
|
3379 |
+ // Double check that the buddy has the same caller ID as the incoming call |
|
3380 |
+ // With Buddies that are contacts, eg +441234567890 <+441234567890> leave as is |
|
3381 |
+ if(buddyObj.type == "extension" && buddyObj.CallerIDName != callerID){ |
|
3382 |
+ UpdateBuddyCalerID(buddyObj, callerID); |
|
3383 |
+ } |
|
3384 |
+ else if(buddyObj.type == "contact" && callerID != did && buddyObj.CallerIDName != callerID){ |
|
3385 |
+ UpdateBuddyCalerID(buddyObj, callerID); |
|
3386 |
+ } |
|
3387 |
+ } |
|
3388 |
+ var buddy = buddyObj.identity; |
|
3389 |
+ |
|
3390 |
+ // Time Stamp |
|
3391 |
+ window.clearInterval(session.data.callTimer); |
|
3392 |
+ var startTime = moment.utc(); |
|
3393 |
+ session.data.callstart = startTime.format("YYYY-MM-DD HH:mm:ss UTC"); |
|
3394 |
+ $("#contact-" + buddy + "-timer").show(); |
|
3395 |
+ session.data.callTimer = window.setInterval(function(){ |
|
3396 |
+ var now = moment.utc(); |
|
3397 |
+ var duration = moment.duration(now.diff(startTime)); |
|
3398 |
+ $("#contact-" + buddy + "-timer").html(formatShortDuration(duration.asSeconds())); |
|
3399 |
+ }, 1000); |
|
3400 |
+ session.data.buddyId = buddy; |
|
3401 |
+ session.data.calldirection = "inbound"; |
|
3402 |
+ session.data.terminateby = "them"; |
|
3403 |
+ session.data.withvideo = false; |
|
3404 |
+ var videoInvite = false; |
|
3405 |
+ if (session.request.body) { |
|
3406 |
+ // Asterisk 13 PJ_SIP always sends m=video if endpoint has video codec, |
|
3407 |
+ // even if origional invite does not specify video. |
|
3408 |
+ if (session.request.body.indexOf("m=video") > -1) { |
|
3409 |
+ videoInvite = true; |
|
3410 |
+ if (buddyObj.type == "contact"){ |
|
3411 |
+ videoInvite = false; |
|
3412 |
+ } |
|
3413 |
+ } |
|
3414 |
+ } |
|
3415 |
+ |
|
3416 |
+ // Inbound You or They Rejected |
|
3417 |
+ session.on('rejected', function (response, cause) { |
|
3418 |
+ console.log("Call rejected: " + cause); |
|
3419 |
+ |
|
3420 |
+ session.data.reasonCode = response.status_code |
|
3421 |
+ session.data.reasonText = cause |
|
3422 |
+ |
|
3423 |
+ AddCallMessage(buddy, session, response.status_code, cause); |
|
3424 |
+ |
|
3425 |
+ // Custom Web hook |
|
3426 |
+ if(typeof web_hook_on_terminate !== 'undefined') web_hook_on_terminate(session); |
|
3427 |
+ }); |
|
3428 |
+ // They cancelled (Gets called regardless) |
|
3429 |
+ session.on('terminated', function(response, cause) { |
|
3430 |
+ |
|
3431 |
+ // Stop the ringtone |
|
3432 |
+ if(session.data.rinngerObj){ |
|
3433 |
+ session.data.rinngerObj.pause(); |
|
3434 |
+ session.data.rinngerObj.removeAttribute('src'); |
|
3435 |
+ session.data.rinngerObj.load(); |
|
3436 |
+ session.data.rinngerObj = null; |
|
3437 |
+ } |
|
3438 |
+ |
|
3439 |
+ $.jeegoopopup.close(); |
|
3440 |
+ console.log("Call terminated"); |
|
3441 |
+ |
|
3442 |
+ window.clearInterval(session.data.callTimer); |
|
3443 |
+ |
|
3444 |
+ $("#contact-" + buddy + "-timer").html(""); |
|
3445 |
+ $("#contact-" + buddy + "-timer").hide(); |
|
3446 |
+ $("#contact-" + buddy + "-msg").html(""); |
|
3447 |
+ $("#contact-" + buddy + "-msg").hide(); |
|
3448 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3449 |
+ |
|
3450 |
+ RefreshStream(buddyObj); |
|
3451 |
+ updateScroll(buddyObj.identity); |
|
3452 |
+ UpdateBuddyList(); |
|
3453 |
+ }); |
|
3454 |
+ |
|
3455 |
+ // Start Handle Call |
|
3456 |
+ if(DoNotDisturbEnabled || DoNotDisturbPolicy == "enabled") { |
|
3457 |
+ console.log("Do Not Disturb Enabled, rejecting call."); |
|
3458 |
+ RejectCall(buddyObj.identity); |
|
3459 |
+ return; |
|
3460 |
+ } |
|
3461 |
+ if(CurrentCalls >= 1){ |
|
3462 |
+ if(CallWaitingEnabled == false || CallWaitingEnabled == "disabled"){ |
|
3463 |
+ console.log("Call Waiting Disabled, rejecting call."); |
|
3464 |
+ RejectCall(buddyObj.identity); |
|
3465 |
+ return; |
|
3466 |
+ } |
|
3467 |
+ } |
|
3468 |
+ if(AutoAnswerEnabled || AutoAnswerPolicy == "enabled"){ |
|
3469 |
+ if(CurrentCalls == 0){ // There are no other calls, so you can answer |
|
3470 |
+ console.log("Auto Answer Call..."); |
|
3471 |
+ var buddyId = buddyObj.identity; |
|
3472 |
+ window.setTimeout(function(){ |
|
3473 |
+ // If the call is with video, assume the auto answer is also |
|
3474 |
+ // In order for this to work nicely, the recipient must be "ready" to accept video calls |
|
3475 |
+ // In order to ensure video call compatibility (i.e. the recipient must have their web cam in, and working) |
|
3476 |
+ // The NULL video should be configured |
|
3477 |
+ // https://github.com/InnovateAsterisk/Browser-Phone/issues/26 |
|
3478 |
+ if(videoInvite) { |
|
3479 |
+ AnswerVideoCall(buddyId) |
|
3480 |
+ } |
|
3481 |
+ else { |
|
3482 |
+ AnswerAudioCall(buddyId); |
|
3483 |
+ } |
|
3484 |
+ }, 1000); |
|
3485 |
+ |
|
3486 |
+ // Select Buddy |
|
3487 |
+ SelectBuddy(buddyObj.identity); |
|
3488 |
+ return; |
|
3489 |
+ } |
|
3490 |
+ else { |
|
3491 |
+ console.warn("Could not auto answer call, already on a call."); |
|
3492 |
+ } |
|
3493 |
+ } |
|
3494 |
+ |
|
3495 |
+ // Show the Answer Thingy |
|
3496 |
+ $("#contact-" + buddyObj.identity + "-msg").html(lang.incomming_call_from +" " + callerID +" <"+ did +">"); |
|
3497 |
+ $("#contact-" + buddyObj.identity + "-msg").show(); |
|
3498 |
+ if(videoInvite){ |
|
3499 |
+ $("#contact-"+ buddyObj.identity +"-answer-video").show(); |
|
3500 |
+ } |
|
3501 |
+ else { |
|
3502 |
+ $("#contact-"+ buddyObj.identity +"-answer-video").hide(); |
|
3503 |
+ } |
|
3504 |
+ $("#contact-" + buddyObj.identity + "-AnswerCall").show(); |
|
3505 |
+ updateScroll(buddyObj.identity); |
|
3506 |
+ |
|
3507 |
+ // Play Ring Tone if not on the phone |
|
3508 |
+ if(CurrentCalls >= 1){ |
|
3509 |
+ |
|
3510 |
+ // Play Alert |
|
3511 |
+ console.log("Audio:", audioBlobs.CallWaiting.url); |
|
3512 |
+ var rinnger = new Audio(audioBlobs.CallWaiting.blob); |
|
3513 |
+ rinnger.preload = "auto"; |
|
3514 |
+ rinnger.loop = false; |
|
3515 |
+ rinnger.oncanplaythrough = function(e) { |
|
3516 |
+ if (typeof rinnger.sinkId !== 'undefined' && getRingerOutputID() != "default") { |
|
3517 |
+ rinnger.setSinkId(getRingerOutputID()).then(function() { |
|
3518 |
+ console.log("Set sinkId to:", getRingerOutputID()); |
|
3519 |
+ }).catch(function(e){ |
|
3520 |
+ console.warn("Failed not apply setSinkId.", e); |
|
3521 |
+ }); |
|
3522 |
+ } |
|
3523 |
+ // If there has been no interaction with the page at all... this page will not work |
|
3524 |
+ rinnger.play().then(function(){ |
|
3525 |
+ // Audio Is Playing |
|
3526 |
+ }).catch(function(e){ |
|
3527 |
+ console.warn("Unable to play audio file.", e); |
|
3528 |
+ }); |
|
3529 |
+ } |
|
3530 |
+ session.data.rinngerObj = rinnger; |
|
3531 |
+ } else { |
|
3532 |
+ // Play Ring Tone |
|
3533 |
+ console.log("Audio:", audioBlobs.Ringtone.url); |
|
3534 |
+ var rinnger = new Audio(audioBlobs.Ringtone.blob); |
|
3535 |
+ rinnger.preload = "auto"; |
|
3536 |
+ rinnger.loop = true; |
|
3537 |
+ rinnger.oncanplaythrough = function(e) { |
|
3538 |
+ if (typeof rinnger.sinkId !== 'undefined' && getRingerOutputID() != "default") { |
|
3539 |
+ rinnger.setSinkId(getRingerOutputID()).then(function() { |
|
3540 |
+ console.log("Set sinkId to:", getRingerOutputID()); |
|
3541 |
+ }).catch(function(e){ |
|
3542 |
+ console.warn("Failed not apply setSinkId.", e); |
|
3543 |
+ }); |
|
3544 |
+ } |
|
3545 |
+ // If there has been no interaction with the page at all... this page will not work |
|
3546 |
+ rinnger.play().then(function(){ |
|
3547 |
+ // Audio Is Playing |
|
3548 |
+ }).catch(function(e){ |
|
3549 |
+ console.warn("Unable to play audio file.", e); |
|
3550 |
+ }); |
|
3551 |
+ } |
|
3552 |
+ session.data.rinngerObj = rinnger; |
|
3553 |
+ } |
|
3554 |
+ |
|
3555 |
+ $.jeegoopopup.close(); |
|
3556 |
+ |
|
3557 |
+ // Show Call Answer Window |
|
3558 |
+ var callAnswerHtml = '<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
3559 |
+ callAnswerHtml += "<div class=\"UiWindowField scroller\" style=\"text-align:center\">"; |
|
3560 |
+ callAnswerHtml += "<div style=\"font-size: 18px; margin-top:1px\">"+ callerID + "<div>"; |
|
3561 |
+ if(callerID != did) { |
|
3562 |
+ callAnswerHtml += "<div style=\"font-size: 18px; margin-top:1px\"><"+ did + "><div>"; |
|
3563 |
+ } |
|
3564 |
+ callAnswerHtml += "<div class=callAnswerBuddyIcon style=\"background-image: url("+ getPicture(buddyObj.identity) +"); margin-top:6px\"></div>"; |
|
3565 |
+ callAnswerHtml += "<div style=\"margin-top:14px\"><button onclick=\"AnswerAudioCall('"+ buddyObj.identity +"')\" class=answerButton><i class=\"fa fa-phone\"></i> "+ lang.answer_call +"</button></div>"; |
|
3566 |
+ if(videoInvite) { |
|
3567 |
+ callAnswerHtml += "<div style=\"margin-top:11px\"><button onclick=\"AnswerVideoCall('"+ buddyObj.identity +"')\" class=answerButton><i class=\"fa fa-video-camera\"></i> "+ lang.answer_call_with_video +"</button></div>"; |
|
3568 |
+ } |
|
3569 |
+ callAnswerHtml += "<div style=\"margin-top:11px\"><button onclick=\"RejectCall('"+ buddyObj.identity +"')\" class=hangupButton><i class=\"fa fa-phone\"></i> "+ lang.reject_call +"</button></div>"; |
|
3570 |
+ callAnswerHtml += "</div>"; |
|
3571 |
+ |
|
3572 |
+ $.jeegoopopup.open({ |
|
3573 |
+ title: 'Incoming Call', |
|
3574 |
+ html: callAnswerHtml, |
|
3575 |
+ width: '290', |
|
3576 |
+ height: '300', |
|
3577 |
+ center: true, |
|
3578 |
+ scrolling: 'no', |
|
3579 |
+ skinClass: 'jg_popup_basic', |
|
3580 |
+ overlay: true, |
|
3581 |
+ opacity: 50, |
|
3582 |
+ draggable: true, |
|
3583 |
+ resizable: false, |
|
3584 |
+ fadeIn: 0 |
|
3585 |
+ }); |
|
3586 |
+ |
|
3587 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); }); |
|
3588 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
3589 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
3590 |
+ |
|
3591 |
+ // Add a notification badge |
|
3592 |
+ IncreaseMissedBadge(buddyObj.identity); |
|
3593 |
+ |
|
3594 |
+ // Show notification |
|
3595 |
+ // ================= |
|
3596 |
+ if ("Notification" in window) { |
|
3597 |
+ if (getDbItem("Notifications", "") == 1) { |
|
3598 |
+ var noticeOptions = { body: lang.incomming_call_from +" " + callerID +" \""+ did +"\"", icon: getPicture(buddyObj.identity) } |
|
3599 |
+ var inComingCallNotification = new Notification(lang.incomming_call, noticeOptions); |
|
3600 |
+ inComingCallNotification.onclick = function (event) { |
|
3601 |
+ |
|
3602 |
+ var buddyId = buddyObj.identity; |
|
3603 |
+ window.setTimeout(function() { |
|
3604 |
+ // https://github.com/InnovateAsterisk/Browser-Phone/issues/26 |
|
3605 |
+ if(videoInvite) { |
|
3606 |
+ AnswerVideoCall(buddyId) |
|
3607 |
+ } else { |
|
3608 |
+ AnswerAudioCall(buddyId); |
|
3609 |
+ } |
|
3610 |
+ }, 4000); |
|
3611 |
+ |
|
3612 |
+ // Select Buddy |
|
3613 |
+ SelectBuddy(buddyObj.identity); |
|
3614 |
+ |
|
3615 |
+ return; |
|
3616 |
+ } |
|
3617 |
+ } |
|
3618 |
+ } |
|
3619 |
+ |
|
3620 |
+} |
|
3621 |
+ |
|
3622 |
+function AnswerAudioCall(buddy) { |
|
3623 |
+ |
|
3624 |
+ $.jeegoopopup.close(); |
|
3625 |
+ |
|
3626 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
3627 |
+ if(buddyObj == null) { |
|
3628 |
+ console.warn("Audio Answer failed, null buddy"); |
|
3629 |
+ $("#contact-" + buddy + "-msg").html(lang.call_failed); |
|
3630 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3631 |
+ return; |
|
3632 |
+ } |
|
3633 |
+ |
|
3634 |
+ var session = getSession(buddy); |
|
3635 |
+ if (session == null) { |
|
3636 |
+ console.warn("Audio Answer failed, null session"); |
|
3637 |
+ $("#contact-" + buddy + "-msg").html(lang.call_failed); |
|
3638 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3639 |
+ return; |
|
3640 |
+ } |
|
3641 |
+ |
|
3642 |
+ // Stop the ringtone |
|
3643 |
+ if(session.data.rinngerObj){ |
|
3644 |
+ session.data.rinngerObj.pause(); |
|
3645 |
+ session.data.rinngerObj.removeAttribute('src'); |
|
3646 |
+ session.data.rinngerObj.load(); |
|
3647 |
+ session.data.rinngerObj = null; |
|
3648 |
+ } |
|
3649 |
+ |
|
3650 |
+ // Check vitals |
|
3651 |
+ if(HasAudioDevice == false){ |
|
3652 |
+ Alert(lang.alert_no_microphone); |
|
3653 |
+ $("#contact-" + buddy + "-msg").html(lang.call_failed); |
|
3654 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3655 |
+ return; |
|
3656 |
+ } |
|
3657 |
+ $("#contact-" + buddy + "-timer").html(""); |
|
3658 |
+ $("#contact-" + buddy + "-timer").hide(); |
|
3659 |
+ $("#contact-" + buddy + "-msg").html(""); |
|
3660 |
+ $("#contact-" + buddy + "-msg").hide(); |
|
3661 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3662 |
+ |
|
3663 |
+ // Create a new Line and move the session over to the line |
|
3664 |
+ var callerID = session.remoteIdentity.displayName; |
|
3665 |
+ var did = session.remoteIdentity.uri.user; |
|
3666 |
+ newLineNumber = newLineNumber + 1; |
|
3667 |
+ lineObj = new Line(newLineNumber, callerID, did, buddyObj); |
|
3668 |
+ lineObj.SipSession = session; |
|
3669 |
+ lineObj.SipSession.data.line = lineObj.LineNumber; |
|
3670 |
+ lineObj.SipSession.data.buddyId = lineObj.BuddyObj.identity; |
|
3671 |
+ Lines.push(lineObj); |
|
3672 |
+ AddLineHtml(lineObj); |
|
3673 |
+ SelectLine(newLineNumber); |
|
3674 |
+ UpdateBuddyList(); |
|
3675 |
+ |
|
3676 |
+ var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); |
|
3677 |
+ var spdOptions = { |
|
3678 |
+ sessionDescriptionHandlerOptions: { |
|
3679 |
+ constraints: { |
|
3680 |
+ audio: { deviceId : "default" }, |
|
3681 |
+ video: false |
|
3682 |
+ } |
|
3683 |
+ } |
|
3684 |
+ } |
|
3685 |
+ |
|
3686 |
+ // Configure Audio |
|
3687 |
+ var currentAudioDevice = getAudioSrcID(); |
|
3688 |
+ if(currentAudioDevice != "default"){ |
|
3689 |
+ var confirmedAudioDevice = false; |
|
3690 |
+ for (var i = 0; i < AudioinputDevices.length; ++i) { |
|
3691 |
+ if(currentAudioDevice == AudioinputDevices[i].deviceId) { |
|
3692 |
+ confirmedAudioDevice = true; |
|
3693 |
+ break; |
|
3694 |
+ } |
|
3695 |
+ } |
|
3696 |
+ if(confirmedAudioDevice) { |
|
3697 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.deviceId = { exact: currentAudioDevice } |
|
3698 |
+ } |
|
3699 |
+ else { |
|
3700 |
+ console.warn("The audio device you used before is no longer available, default settings applied."); |
|
3701 |
+ localDB.setItem("AudioSrcId", "default"); |
|
3702 |
+ } |
|
3703 |
+ } |
|
3704 |
+ // Add additional Constraints |
|
3705 |
+ if(supportedConstraints.autoGainControl) { |
|
3706 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl = AutoGainControl; |
|
3707 |
+ } |
|
3708 |
+ if(supportedConstraints.echoCancellation) { |
|
3709 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation = EchoCancellation; |
|
3710 |
+ } |
|
3711 |
+ if(supportedConstraints.noiseSuppression) { |
|
3712 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression = NoiseSuppression; |
|
3713 |
+ } |
|
3714 |
+ |
|
3715 |
+ // Send Answer |
|
3716 |
+ lineObj.SipSession.accept(spdOptions); |
|
3717 |
+ lineObj.SipSession.data.withvideo = false; |
|
3718 |
+ lineObj.SipSession.data.VideoSourceDevice = null; |
|
3719 |
+ lineObj.SipSession.data.AudioSourceDevice = getAudioSrcID(); |
|
3720 |
+ lineObj.SipSession.data.AudioOutputDevice = getAudioOutputID(); |
|
3721 |
+ |
|
3722 |
+ // Wire up UI |
|
3723 |
+ wireupAudioSession(lineObj); |
|
3724 |
+ $("#contact-" + buddy + "-msg").html(lang.call_in_progress); |
|
3725 |
+ |
|
3726 |
+ // Clear Answer Buttons |
|
3727 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3728 |
+} |
|
3729 |
+ |
|
3730 |
+function AnswerVideoCall(buddy) { |
|
3731 |
+ |
|
3732 |
+ $.jeegoopopup.close(); |
|
3733 |
+ |
|
3734 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
3735 |
+ if(buddyObj == null) { |
|
3736 |
+ console.warn("Audio Answer failed, null buddy"); |
|
3737 |
+ $("#contact-" + buddy + "-msg").html(lang.call_failed); |
|
3738 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3739 |
+ return; |
|
3740 |
+ } |
|
3741 |
+ |
|
3742 |
+ var session = getSession(buddy); |
|
3743 |
+ if (session == null) { |
|
3744 |
+ console.warn("Video Answer failed, null session"); |
|
3745 |
+ $("#contact-" + buddy + "-msg").html(lang.call_failed); |
|
3746 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3747 |
+ return; |
|
3748 |
+ } |
|
3749 |
+ |
|
3750 |
+ // Stop the ringtone |
|
3751 |
+ if(session.data.rinngerObj){ |
|
3752 |
+ session.data.rinngerObj.pause(); |
|
3753 |
+ session.data.rinngerObj.removeAttribute('src'); |
|
3754 |
+ session.data.rinngerObj.load(); |
|
3755 |
+ session.data.rinngerObj = null; |
|
3756 |
+ } |
|
3757 |
+ |
|
3758 |
+ // Check vitals |
|
3759 |
+ if(HasAudioDevice == false){ |
|
3760 |
+ Alert(lang.alert_no_microphone); |
|
3761 |
+ $("#contact-" + buddy + "-msg").html(lang.call_failed); |
|
3762 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3763 |
+ return; |
|
3764 |
+ } |
|
3765 |
+ if(HasVideoDevice == false){ |
|
3766 |
+ console.warn("No video devices (webcam) found, switching to audio call."); |
|
3767 |
+ AnswerAudioCall(buddy); |
|
3768 |
+ return; |
|
3769 |
+ } |
|
3770 |
+ $("#contact-" + buddy + "-timer").html(""); |
|
3771 |
+ $("#contact-" + buddy + "-timer").hide(); |
|
3772 |
+ $("#contact-" + buddy + "-msg").html(""); |
|
3773 |
+ $("#contact-" + buddy + "-msg").hide(); |
|
3774 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3775 |
+ |
|
3776 |
+ // Create a new Line and move the session over to the line |
|
3777 |
+ var callerID = session.remoteIdentity.displayName; |
|
3778 |
+ var did = session.remoteIdentity.uri.user; |
|
3779 |
+ newLineNumber = newLineNumber + 1; |
|
3780 |
+ lineObj = new Line(newLineNumber, callerID, did, buddyObj); |
|
3781 |
+ lineObj.SipSession = session; |
|
3782 |
+ lineObj.SipSession.data.line = lineObj.LineNumber; |
|
3783 |
+ lineObj.SipSession.data.buddyId = lineObj.BuddyObj.identity; |
|
3784 |
+ Lines.push(lineObj); |
|
3785 |
+ AddLineHtml(lineObj); |
|
3786 |
+ SelectLine(newLineNumber); |
|
3787 |
+ UpdateBuddyList(); |
|
3788 |
+ |
|
3789 |
+ var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); |
|
3790 |
+ var spdOptions = { |
|
3791 |
+ sessionDescriptionHandlerOptions: { |
|
3792 |
+ constraints: { |
|
3793 |
+ audio: { deviceId : "default" }, |
|
3794 |
+ video: { deviceId : "default" } |
|
3795 |
+ } |
|
3796 |
+ } |
|
3797 |
+ } |
|
3798 |
+ |
|
3799 |
+ // Configure Audio |
|
3800 |
+ var currentAudioDevice = getAudioSrcID(); |
|
3801 |
+ if(currentAudioDevice != "default"){ |
|
3802 |
+ var confirmedAudioDevice = false; |
|
3803 |
+ for (var i = 0; i < AudioinputDevices.length; ++i) { |
|
3804 |
+ if(currentAudioDevice == AudioinputDevices[i].deviceId) { |
|
3805 |
+ confirmedAudioDevice = true; |
|
3806 |
+ break; |
|
3807 |
+ } |
|
3808 |
+ } |
|
3809 |
+ if(confirmedAudioDevice) { |
|
3810 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.deviceId = { exact: currentAudioDevice } |
|
3811 |
+ } |
|
3812 |
+ else { |
|
3813 |
+ console.warn("The audio device you used before is no longer available, default settings applied."); |
|
3814 |
+ localDB.setItem("AudioSrcId", "default"); |
|
3815 |
+ } |
|
3816 |
+ } |
|
3817 |
+ // Add additional Constraints |
|
3818 |
+ if(supportedConstraints.autoGainControl) { |
|
3819 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl = AutoGainControl; |
|
3820 |
+ } |
|
3821 |
+ if(supportedConstraints.echoCancellation) { |
|
3822 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation = EchoCancellation; |
|
3823 |
+ } |
|
3824 |
+ if(supportedConstraints.noiseSuppression) { |
|
3825 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression = NoiseSuppression; |
|
3826 |
+ } |
|
3827 |
+ |
|
3828 |
+ // Configure Video |
|
3829 |
+ var currentVideoDevice = getVideoSrcID(); |
|
3830 |
+ if(currentVideoDevice != "default"){ |
|
3831 |
+ var confirmedVideoDevice = false; |
|
3832 |
+ for (var i = 0; i < VideoinputDevices.length; ++i) { |
|
3833 |
+ if(currentVideoDevice == VideoinputDevices[i].deviceId) { |
|
3834 |
+ confirmedVideoDevice = true; |
|
3835 |
+ break; |
|
3836 |
+ } |
|
3837 |
+ } |
|
3838 |
+ if(confirmedVideoDevice){ |
|
3839 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.deviceId = { exact: currentVideoDevice } |
|
3840 |
+ } |
|
3841 |
+ else { |
|
3842 |
+ console.warn("The video device you used before is no longer available, default settings applied."); |
|
3843 |
+ localDB.setItem("VideoSrcId", "default"); // resets for later and subsequent calls |
|
3844 |
+ } |
|
3845 |
+ } |
|
3846 |
+ // Add additional Constraints |
|
3847 |
+ if(supportedConstraints.frameRate && maxFrameRate != "") { |
|
3848 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.frameRate = maxFrameRate; |
|
3849 |
+ } |
|
3850 |
+ if(supportedConstraints.height && videoHeight != "") { |
|
3851 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.height = videoHeight; |
|
3852 |
+ } |
|
3853 |
+ if(supportedConstraints.aspectRatio && videoAspectRatio != "") { |
|
3854 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.aspectRatio = videoAspectRatio; |
|
3855 |
+ } |
|
3856 |
+ |
|
3857 |
+ // Send Answer |
|
3858 |
+ lineObj.SipSession.data.withvideo = true; |
|
3859 |
+ lineObj.SipSession.data.VideoSourceDevice = getVideoSrcID(); |
|
3860 |
+ lineObj.SipSession.data.AudioSourceDevice = getAudioSrcID(); |
|
3861 |
+ lineObj.SipSession.data.AudioOutputDevice = getAudioOutputID(); |
|
3862 |
+ |
|
3863 |
+ // Send Answer |
|
3864 |
+ // If this fails, it must still wireup the call so we can manually close it |
|
3865 |
+ $("#contact-" + buddy + "-msg").html(lang.call_in_progress); |
|
3866 |
+ // Wire up UI |
|
3867 |
+ wireupVideoSession(lineObj); |
|
3868 |
+ |
|
3869 |
+ try{ |
|
3870 |
+ lineObj.SipSession.accept(spdOptions); |
|
3871 |
+ if(StartVideoFullScreen) ExpandVideoArea(lineObj.LineNumber); |
|
3872 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3873 |
+ } |
|
3874 |
+ catch(e){ |
|
3875 |
+ console.warn("Failed to answer call", e, lineObj.SipSession); |
|
3876 |
+ teardownSession(lineObj, 500, "Client Error"); |
|
3877 |
+ } |
|
3878 |
+ |
|
3879 |
+} |
|
3880 |
+ |
|
3881 |
+function RejectCall(buddy) { |
|
3882 |
+ var session = getSession(buddy); |
|
3883 |
+ if (session == null) { |
|
3884 |
+ console.warn("Reject failed, null session"); |
|
3885 |
+ $("#contact-" + buddy + "-msg").html(lang.call_failed); |
|
3886 |
+ $("#contact-" + buddy + "-AnswerCall").hide(); |
|
3887 |
+ } |
|
3888 |
+ session.data.terminateby = "us"; |
|
3889 |
+ session.reject({ |
|
3890 |
+ statusCode: 486, |
|
3891 |
+ reasonPhrase: "Rejected by us" |
|
3892 |
+ }); |
|
3893 |
+ $("#contact-" + buddy + "-msg").html(lang.call_rejected); |
|
3894 |
+} |
|
3895 |
+ |
|
3896 |
+// Session Wireup |
|
3897 |
+// ============== |
|
3898 |
+function wireupAudioSession(lineObj) { |
|
3899 |
+ if (lineObj == null) return; |
|
3900 |
+ |
|
3901 |
+ var MessageObjId = "#line-" + lineObj.LineNumber + "-msg"; |
|
3902 |
+ var session = lineObj.SipSession; |
|
3903 |
+ |
|
3904 |
+ session.on('progress', function (response) { |
|
3905 |
+ // Provisional 1xx |
|
3906 |
+ if(response.status_code == 100){ |
|
3907 |
+ $(MessageObjId).html(lang.trying); |
|
3908 |
+ } else if(response.status_code == 180){ |
|
3909 |
+ $(MessageObjId).html(lang.ringing); |
|
3910 |
+ |
|
3911 |
+ var soundFile = audioBlobs.EarlyMedia_European; |
|
3912 |
+ if(UserLocale().indexOf("us") > -1) soundFile = audioBlobs.EarlyMedia_US; |
|
3913 |
+ if(UserLocale().indexOf("gb") > -1) soundFile = audioBlobs.EarlyMedia_UK; |
|
3914 |
+ if(UserLocale().indexOf("au") > -1) soundFile = audioBlobs.EarlyMedia_Australia; |
|
3915 |
+ if(UserLocale().indexOf("jp") > -1) soundFile = audioBlobs.EarlyMedia_Japan; |
|
3916 |
+ |
|
3917 |
+ // Play Early Media |
|
3918 |
+ console.log("Audio:", soundFile.url); |
|
3919 |
+ var earlyMedia = new Audio(soundFile.blob); |
|
3920 |
+ earlyMedia.preload = "auto"; |
|
3921 |
+ earlyMedia.loop = true; |
|
3922 |
+ earlyMedia.oncanplaythrough = function(e) { |
|
3923 |
+ if (typeof earlyMedia.sinkId !== 'undefined' && getAudioOutputID() != "default") { |
|
3924 |
+ earlyMedia.setSinkId(getAudioOutputID()).then(function() { |
|
3925 |
+ console.log("Set sinkId to:", getAudioOutputID()); |
|
3926 |
+ }).catch(function(e){ |
|
3927 |
+ console.warn("Failed not apply setSinkId.", e); |
|
3928 |
+ }); |
|
3929 |
+ } |
|
3930 |
+ earlyMedia.play().then(function(){ |
|
3931 |
+ // Audio Is Playing |
|
3932 |
+ }).catch(function(e){ |
|
3933 |
+ console.warn("Unable to play audio file.", e); |
|
3934 |
+ }); |
|
3935 |
+ } |
|
3936 |
+ session.data.earlyMedia = earlyMedia; |
|
3937 |
+ } else { |
|
3938 |
+ $(MessageObjId).html(response.reason_phrase + "..."); |
|
3939 |
+ } |
|
3940 |
+ |
|
3941 |
+ // Custom Web hook |
|
3942 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("progress", session); |
|
3943 |
+ }); |
|
3944 |
+ session.on('trackAdded', function () { |
|
3945 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
3946 |
+ |
|
3947 |
+ // Gets Remote Audio Track (Local audio is setup via initial GUM) |
|
3948 |
+ var remoteStream = new MediaStream(); |
|
3949 |
+ pc.getReceivers().forEach(function (receiver) { |
|
3950 |
+ if(receiver.track && receiver.track.kind == "audio"){ |
|
3951 |
+ remoteStream.addTrack(receiver.track); |
|
3952 |
+ } |
|
3953 |
+ }); |
|
3954 |
+ var remoteAudio = $("#line-" + lineObj.LineNumber + "-remoteAudio").get(0); |
|
3955 |
+ remoteAudio.srcObject = remoteStream; |
|
3956 |
+ remoteAudio.onloadedmetadata = function(e) { |
|
3957 |
+ if (typeof remoteAudio.sinkId !== 'undefined') { |
|
3958 |
+ remoteAudio.setSinkId(getAudioOutputID()).then(function(){ |
|
3959 |
+ console.log("sinkId applied: "+ getAudioOutputID()); |
|
3960 |
+ }).catch(function(e){ |
|
3961 |
+ console.warn("Error using setSinkId: ", e); |
|
3962 |
+ }); |
|
3963 |
+ } |
|
3964 |
+ remoteAudio.play(); |
|
3965 |
+ } |
|
3966 |
+ |
|
3967 |
+ // Custom Web hook |
|
3968 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("trackAdded", session); |
|
3969 |
+ }); |
|
3970 |
+ session.on('accepted', function (data) { |
|
3971 |
+ |
|
3972 |
+ if(session.data.earlyMedia){ |
|
3973 |
+ session.data.earlyMedia.pause(); |
|
3974 |
+ session.data.earlyMedia.removeAttribute('src'); |
|
3975 |
+ session.data.earlyMedia.load(); |
|
3976 |
+ session.data.earlyMedia = null; |
|
3977 |
+ } |
|
3978 |
+ |
|
3979 |
+ window.clearInterval(session.data.callTimer); |
|
3980 |
+ var startTime = moment.utc(); |
|
3981 |
+ session.data.callTimer = window.setInterval(function(){ |
|
3982 |
+ var now = moment.utc(); |
|
3983 |
+ var duration = moment.duration(now.diff(startTime)); |
|
3984 |
+ $("#line-" + lineObj.LineNumber + "-timer").html(formatShortDuration(duration.asSeconds())); |
|
3985 |
+ }, 1000); |
|
3986 |
+ |
|
3987 |
+ if(RecordAllCalls || CallRecordingPolicy == "enabled") { |
|
3988 |
+ StartRecording(lineObj.LineNumber); |
|
3989 |
+ } |
|
3990 |
+ |
|
3991 |
+ $("#line-" + lineObj.LineNumber + "-progress").hide(); |
|
3992 |
+ $("#line-" + lineObj.LineNumber + "-VideoCall").hide(); |
|
3993 |
+ $("#line-" + lineObj.LineNumber + "-ActiveCall").show(); |
|
3994 |
+ |
|
3995 |
+ // Audo Monitoring |
|
3996 |
+ lineObj.LocalSoundMeter = StartLocalAudioMediaMonitoring(lineObj.LineNumber, session); |
|
3997 |
+ lineObj.RemoteSoundMeter = StartRemoteAudioMediaMonitoring(lineObj.LineNumber, session); |
|
3998 |
+ |
|
3999 |
+ $(MessageObjId).html(lang.call_in_progress); |
|
4000 |
+ |
|
4001 |
+ updateLineScroll(lineObj.LineNumber); |
|
4002 |
+ |
|
4003 |
+ UpdateBuddyList(); |
|
4004 |
+ |
|
4005 |
+ // Custom Web hook |
|
4006 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("accepted", session); |
|
4007 |
+ }); |
|
4008 |
+ session.on('rejected', function (response, cause) { |
|
4009 |
+ // Should only apply befor answer |
|
4010 |
+ $(MessageObjId).html(lang.call_rejected +": " + cause); |
|
4011 |
+ console.log("Call rejected: " + cause); |
|
4012 |
+ teardownSession(lineObj, response.status_code, response.reason_phrase); |
|
4013 |
+ }); |
|
4014 |
+ session.on('failed', function (response, cause) { |
|
4015 |
+ $(MessageObjId).html(lang.call_failed + ": " + cause); |
|
4016 |
+ console.log("Call failed: " + cause); |
|
4017 |
+ teardownSession(lineObj, 0, "Call failed"); |
|
4018 |
+ }); |
|
4019 |
+ session.on('cancel', function () { |
|
4020 |
+ $(MessageObjId).html(lang.call_cancelled); |
|
4021 |
+ console.log("Call Cancelled"); |
|
4022 |
+ teardownSession(lineObj, 0, "Cancelled by caller"); |
|
4023 |
+ }); |
|
4024 |
+ // referRequested |
|
4025 |
+ // replaced |
|
4026 |
+ session.on('bye', function () { |
|
4027 |
+ $(MessageObjId).html(lang.call_ended); |
|
4028 |
+ console.log("Call ended, bye!"); |
|
4029 |
+ teardownSession(lineObj, 16, "Normal Call clearing"); |
|
4030 |
+ }); |
|
4031 |
+ session.on('terminated', function (message, cause) { |
|
4032 |
+ $(MessageObjId).html(lang.call_ended); |
|
4033 |
+ console.log("Session terminated"); |
|
4034 |
+ teardownSession(lineObj, 16, "Normal Call clearing"); |
|
4035 |
+ }); |
|
4036 |
+ session.on('reinvite', function (session) { |
|
4037 |
+ console.log("Session reinvited!"); |
|
4038 |
+ }); |
|
4039 |
+ //dtmf |
|
4040 |
+ session.on('directionChanged', function() { |
|
4041 |
+ var direction = session.sessionDescriptionHandler.getDirection(); |
|
4042 |
+ console.log("Direction Change: ", direction); |
|
4043 |
+ |
|
4044 |
+ // Custom Web hook |
|
4045 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("directionChanged", session); |
|
4046 |
+ }); |
|
4047 |
+ |
|
4048 |
+ $("#line-" + lineObj.LineNumber + "-btn-settings").removeAttr('disabled'); |
|
4049 |
+ $("#line-" + lineObj.LineNumber + "-btn-audioCall").prop('disabled','disabled'); |
|
4050 |
+ $("#line-" + lineObj.LineNumber + "-btn-videoCall").prop('disabled','disabled'); |
|
4051 |
+ $("#line-" + lineObj.LineNumber + "-btn-search").removeAttr('disabled'); |
|
4052 |
+ $("#line-" + lineObj.LineNumber + "-btn-remove").prop('disabled','disabled'); |
|
4053 |
+ |
|
4054 |
+ $("#line-" + lineObj.LineNumber + "-progress").show(); |
|
4055 |
+ $("#line-" + lineObj.LineNumber + "-msg").show(); |
|
4056 |
+ |
|
4057 |
+ if(lineObj.BuddyObj.type == "group") { |
|
4058 |
+ $("#line-" + lineObj.LineNumber + "-conference").show(); |
|
4059 |
+ } |
|
4060 |
+ else { |
|
4061 |
+ $("#line-" + lineObj.LineNumber + "-conference").hide(); |
|
4062 |
+ } |
|
4063 |
+ |
|
4064 |
+ updateLineScroll(lineObj.LineNumber); |
|
4065 |
+ |
|
4066 |
+ UpdateUI(); |
|
4067 |
+} |
|
4068 |
+ |
|
4069 |
+function wireupVideoSession(lineObj) { |
|
4070 |
+ if (lineObj == null) return; |
|
4071 |
+ |
|
4072 |
+ var MessageObjId = "#line-" + lineObj.LineNumber + "-msg"; |
|
4073 |
+ var session = lineObj.SipSession; |
|
4074 |
+ |
|
4075 |
+ session.on('trackAdded', function () { |
|
4076 |
+ // Gets remote tracks |
|
4077 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
4078 |
+ var remoteAudioStream = new MediaStream(); |
|
4079 |
+ var remoteVideoStream = new MediaStream(); |
|
4080 |
+ pc.getReceivers().forEach(function (receiver) { |
|
4081 |
+ if(receiver.track){ |
|
4082 |
+ if(receiver.track.kind == "audio"){ |
|
4083 |
+ remoteAudioStream.addTrack(receiver.track); |
|
4084 |
+ } |
|
4085 |
+ if(receiver.track.kind == "video"){ |
|
4086 |
+ remoteVideoStream.addTrack(receiver.track); |
|
4087 |
+ } |
|
4088 |
+ } |
|
4089 |
+ }); |
|
4090 |
+ |
|
4091 |
+ if (remoteAudioStream.getAudioTracks().length >= 1) { |
|
4092 |
+ var remoteAudio = $("#line-" + lineObj.LineNumber + "-remoteAudio").get(0); |
|
4093 |
+ remoteAudio.srcObject = remoteAudioStream; |
|
4094 |
+ remoteAudio.onloadedmetadata = function(e) { |
|
4095 |
+ if (typeof remoteAudio.sinkId !== 'undefined') { |
|
4096 |
+ remoteAudio.setSinkId(getAudioOutputID()).then(function(){ |
|
4097 |
+ console.log("sinkId applied: "+ getAudioOutputID()); |
|
4098 |
+ }).catch(function(e){ |
|
4099 |
+ console.warn("Error using setSinkId: ", e); |
|
4100 |
+ }); |
|
4101 |
+ } |
|
4102 |
+ remoteAudio.play(); |
|
4103 |
+ } |
|
4104 |
+ } |
|
4105 |
+ |
|
4106 |
+ if (remoteVideoStream.getVideoTracks().length >= 1) { |
|
4107 |
+ var remoteVideo = $("#line-" + lineObj.LineNumber + "-remoteVideo").get(0); |
|
4108 |
+ remoteVideo.srcObject = remoteVideoStream; |
|
4109 |
+ remoteVideo.onloadedmetadata = function(e) { |
|
4110 |
+ remoteVideo.play(); |
|
4111 |
+ } |
|
4112 |
+ } |
|
4113 |
+ |
|
4114 |
+ // Note: There appears to be a bug in the peerConnection.getSenders() |
|
4115 |
+ // The array returns but may or may not be fully populated by the RTCRtpSender |
|
4116 |
+ // The track property appears to be null initially and then moments later populated. |
|
4117 |
+ // This does not appear to be the case when originating a call, mostly when receiving a call. |
|
4118 |
+ window.setTimeout(function(){ |
|
4119 |
+ var localVideoStream = new MediaStream(); |
|
4120 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
4121 |
+ pc.getSenders().forEach(function (sender) { |
|
4122 |
+ if(sender.track && sender.track.kind == "video"){ |
|
4123 |
+ localVideoStream.addTrack(sender.track); |
|
4124 |
+ } |
|
4125 |
+ }); |
|
4126 |
+ var localVideo = $("#line-" + lineObj.LineNumber + "-localVideo").get(0); |
|
4127 |
+ localVideo.srcObject = localVideoStream; |
|
4128 |
+ localVideo.onloadedmetadata = function(e) { |
|
4129 |
+ localVideo.play(); |
|
4130 |
+ } |
|
4131 |
+ }, 1000); |
|
4132 |
+ |
|
4133 |
+ // Custom Web hook |
|
4134 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("trackAdded", session); |
|
4135 |
+ }); |
|
4136 |
+ session.on('progress', function (response) { |
|
4137 |
+ // Provisional 1xx |
|
4138 |
+ if(response.status_code == 100){ |
|
4139 |
+ $(MessageObjId).html(lang.trying); |
|
4140 |
+ } else if(response.status_code == 180){ |
|
4141 |
+ $(MessageObjId).html(lang.ringing); |
|
4142 |
+ |
|
4143 |
+ var soundFile = audioBlobs.EarlyMedia_European; |
|
4144 |
+ if(UserLocale().indexOf("us") > -1) soundFile = audioBlobs.EarlyMedia_US; |
|
4145 |
+ if(UserLocale().indexOf("gb") > -1) soundFile = audioBlobs.EarlyMedia_UK; |
|
4146 |
+ if(UserLocale().indexOf("au") > -1) soundFile = audioBlobs.EarlyMedia_Australia; |
|
4147 |
+ if(UserLocale().indexOf("jp") > -1) soundFile = audioBlobs.EarlyMedia_Japan; |
|
4148 |
+ |
|
4149 |
+ // Play Early Media |
|
4150 |
+ console.log("Audio:", soundFile.url); |
|
4151 |
+ var earlyMedia = new Audio(soundFile.blob); |
|
4152 |
+ earlyMedia.preload = "auto"; |
|
4153 |
+ earlyMedia.loop = true; |
|
4154 |
+ earlyMedia.oncanplaythrough = function(e) { |
|
4155 |
+ if (typeof earlyMedia.sinkId !== 'undefined' && getAudioOutputID() != "default") { |
|
4156 |
+ earlyMedia.setSinkId(getAudioOutputID()).then(function() { |
|
4157 |
+ console.log("Set sinkId to:", getAudioOutputID()); |
|
4158 |
+ }).catch(function(e){ |
|
4159 |
+ console.warn("Failed not apply setSinkId.", e); |
|
4160 |
+ }); |
|
4161 |
+ } |
|
4162 |
+ earlyMedia.play().then(function(){ |
|
4163 |
+ // Audio Is Playing |
|
4164 |
+ }).catch(function(e){ |
|
4165 |
+ console.warn("Unable to play audio file.", e); |
|
4166 |
+ }); |
|
4167 |
+ } |
|
4168 |
+ session.data.earlyMedia = earlyMedia; |
|
4169 |
+ } else { |
|
4170 |
+ $(MessageObjId).html(response.reason_phrase + "..."); |
|
4171 |
+ } |
|
4172 |
+ |
|
4173 |
+ // Custom Web hook |
|
4174 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("progress", session); |
|
4175 |
+ }); |
|
4176 |
+ session.on('accepted', function (data) { |
|
4177 |
+ |
|
4178 |
+ if(session.data.earlyMedia){ |
|
4179 |
+ session.data.earlyMedia.pause(); |
|
4180 |
+ session.data.earlyMedia.removeAttribute('src'); |
|
4181 |
+ session.data.earlyMedia.load(); |
|
4182 |
+ session.data.earlyMedia = null; |
|
4183 |
+ } |
|
4184 |
+ |
|
4185 |
+ window.clearInterval(session.data.callTimer); |
|
4186 |
+ $("#line-" + lineObj.LineNumber + "-timer").show(); |
|
4187 |
+ var startTime = moment.utc(); |
|
4188 |
+ session.data.callTimer = window.setInterval(function(){ |
|
4189 |
+ var now = moment.utc(); |
|
4190 |
+ var duration = moment.duration(now.diff(startTime)); |
|
4191 |
+ $("#line-" + lineObj.LineNumber + "-timer").html(formatShortDuration(duration.asSeconds())); |
|
4192 |
+ }, 1000); |
|
4193 |
+ |
|
4194 |
+ if(RecordAllCalls || CallRecordingPolicy == "enabled") { |
|
4195 |
+ StartRecording(lineObj.LineNumber); |
|
4196 |
+ } |
|
4197 |
+ |
|
4198 |
+ $("#line-"+ lineObj.LineNumber +"-progress").hide(); |
|
4199 |
+ $("#line-"+ lineObj.LineNumber +"-VideoCall").show(); |
|
4200 |
+ $("#line-"+ lineObj.LineNumber +"-ActiveCall").show(); |
|
4201 |
+ |
|
4202 |
+ $("#line-"+ lineObj.LineNumber +"-btn-Conference").hide(); // Cannot conference a Video Call (Yet...) |
|
4203 |
+ $("#line-"+ lineObj.LineNumber +"-btn-CancelConference").hide(); |
|
4204 |
+ $("#line-"+ lineObj.LineNumber +"-Conference").hide(); |
|
4205 |
+ |
|
4206 |
+ $("#line-"+ lineObj.LineNumber +"-btn-Transfer").hide(); // Cannot transfer a Video Call (Yet...) |
|
4207 |
+ $("#line-"+ lineObj.LineNumber +"-btn-CancelTransfer").hide(); |
|
4208 |
+ $("#line-"+ lineObj.LineNumber +"-Transfer").hide(); |
|
4209 |
+ |
|
4210 |
+ // Default to use Camera |
|
4211 |
+ $("#line-"+ lineObj.LineNumber +"-src-camera").prop("disabled", true); |
|
4212 |
+ $("#line-"+ lineObj.LineNumber +"-src-canvas").prop("disabled", false); |
|
4213 |
+ $("#line-"+ lineObj.LineNumber +"-src-desktop").prop("disabled", false); |
|
4214 |
+ $("#line-"+ lineObj.LineNumber +"-src-video").prop("disabled", false); |
|
4215 |
+ |
|
4216 |
+ updateLineScroll(lineObj.LineNumber); |
|
4217 |
+ |
|
4218 |
+ // Start Audio Monitoring |
|
4219 |
+ lineObj.LocalSoundMeter = StartLocalAudioMediaMonitoring(lineObj.LineNumber, session); |
|
4220 |
+ lineObj.RemoteSoundMeter = StartRemoteAudioMediaMonitoring(lineObj.LineNumber, session); |
|
4221 |
+ |
|
4222 |
+ $(MessageObjId).html(lang.call_in_progress); |
|
4223 |
+ |
|
4224 |
+ if(StartVideoFullScreen) ExpandVideoArea(lineObj.LineNumber); |
|
4225 |
+ |
|
4226 |
+ // Custom Web hook |
|
4227 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("accepted", session); |
|
4228 |
+ }); |
|
4229 |
+ session.on('rejected', function (response, cause) { |
|
4230 |
+ // Should only apply before answer |
|
4231 |
+ $(MessageObjId).html(lang.call_rejected +": "+ cause); |
|
4232 |
+ console.log("Call rejected: "+ cause); |
|
4233 |
+ teardownSession(lineObj, response.status_code, response.reason_phrase); |
|
4234 |
+ }); |
|
4235 |
+ session.on('failed', function (response, cause) { |
|
4236 |
+ $(MessageObjId).html(lang.call_failed +": "+ cause); |
|
4237 |
+ console.log("Call failed: "+ cause); |
|
4238 |
+ teardownSession(lineObj, 0, "call failed"); |
|
4239 |
+ }); |
|
4240 |
+ session.on('cancel', function () { |
|
4241 |
+ $(MessageObjId).html(lang.call_cancelled); |
|
4242 |
+ console.log("Call Cancelled"); |
|
4243 |
+ teardownSession(lineObj, 0, "Cancelled by caller"); |
|
4244 |
+ }); |
|
4245 |
+ // referRequested |
|
4246 |
+ // replaced |
|
4247 |
+ session.on('bye', function () { |
|
4248 |
+ $(MessageObjId).html(lang.call_ended); |
|
4249 |
+ console.log("Call ended, bye!"); |
|
4250 |
+ teardownSession(lineObj, 16, "Normal Call clearing"); |
|
4251 |
+ }); |
|
4252 |
+ session.on('terminated', function (message, cause) { |
|
4253 |
+ $(MessageObjId).html(lang.call_ended); |
|
4254 |
+ console.log("Session terminated"); |
|
4255 |
+ teardownSession(lineObj, 16, "Normal Call clearing"); |
|
4256 |
+ }); |
|
4257 |
+ session.on('reinvite', function (session) { |
|
4258 |
+ console.log("Session reinvited!"); |
|
4259 |
+ }); |
|
4260 |
+ // dtmf |
|
4261 |
+ session.on('directionChanged', function() { |
|
4262 |
+ var direction = session.sessionDescriptionHandler.getDirection(); |
|
4263 |
+ console.log("Direction Change: ", direction); |
|
4264 |
+ |
|
4265 |
+ // Custom Web hook |
|
4266 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("directionChanged", session); |
|
4267 |
+ }); |
|
4268 |
+ |
|
4269 |
+ $("#line-" + lineObj.LineNumber + "-btn-settings").removeAttr('disabled'); |
|
4270 |
+ $("#line-" + lineObj.LineNumber + "-btn-audioCall").prop('disabled','disabled'); |
|
4271 |
+ $("#line-" + lineObj.LineNumber + "-btn-videoCall").prop('disabled','disabled'); |
|
4272 |
+ $("#line-" + lineObj.LineNumber + "-btn-search").removeAttr('disabled'); |
|
4273 |
+ $("#line-" + lineObj.LineNumber + "-btn-remove").prop('disabled','disabled'); |
|
4274 |
+ |
|
4275 |
+ $("#line-" + lineObj.LineNumber + "-progress").show(); |
|
4276 |
+ $("#line-" + lineObj.LineNumber + "-msg").show(); |
|
4277 |
+ |
|
4278 |
+ updateLineScroll(lineObj.LineNumber); |
|
4279 |
+ |
|
4280 |
+ UpdateUI(); |
|
4281 |
+} |
|
4282 |
+function teardownSession(lineObj, reasonCode, reasonText) { |
|
4283 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
4284 |
+ |
|
4285 |
+ var session = lineObj.SipSession; |
|
4286 |
+ if(session.data.teardownComplete == true) return; |
|
4287 |
+ session.data.teardownComplete = true; // Run this code only once |
|
4288 |
+ |
|
4289 |
+ session.data.reasonCode = reasonCode |
|
4290 |
+ session.data.reasonText = reasonText |
|
4291 |
+ |
|
4292 |
+ // Call UI |
|
4293 |
+ $.jeegoopopup.close(); |
|
4294 |
+ |
|
4295 |
+ // End any child calls |
|
4296 |
+ if(session.data.childsession){ |
|
4297 |
+ try{ |
|
4298 |
+ if(session.data.childsession.status == SIP.Session.C.STATUS_CONFIRMED){ |
|
4299 |
+ session.data.childsession.bye(); |
|
4300 |
+ } |
|
4301 |
+ else{ |
|
4302 |
+ session.data.childsession.cancel(); |
|
4303 |
+ } |
|
4304 |
+ } catch(e){} |
|
4305 |
+ } |
|
4306 |
+ session.data.childsession = null; |
|
4307 |
+ |
|
4308 |
+ // Mixed Tracks |
|
4309 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
4310 |
+ session.data.AudioSourceTrack.stop(); |
|
4311 |
+ session.data.AudioSourceTrack = null; |
|
4312 |
+ } |
|
4313 |
+ // Stop any Early Media |
|
4314 |
+ if(session.data.earlyMedia){ |
|
4315 |
+ session.data.earlyMedia.pause(); |
|
4316 |
+ session.data.earlyMedia.removeAttribute('src'); |
|
4317 |
+ session.data.earlyMedia.load(); |
|
4318 |
+ session.data.earlyMedia = null; |
|
4319 |
+ } |
|
4320 |
+ |
|
4321 |
+ // Stop Recording if we are |
|
4322 |
+ StopRecording(lineObj.LineNumber,true); |
|
4323 |
+ |
|
4324 |
+ // Audio Meters |
|
4325 |
+ if(lineObj.LocalSoundMeter != null){ |
|
4326 |
+ lineObj.LocalSoundMeter.stop(); |
|
4327 |
+ lineObj.LocalSoundMeter = null; |
|
4328 |
+ } |
|
4329 |
+ if(lineObj.RemoteSoundMeter != null){ |
|
4330 |
+ lineObj.RemoteSoundMeter.stop(); |
|
4331 |
+ lineObj.RemoteSoundMeter = null; |
|
4332 |
+ } |
|
4333 |
+ |
|
4334 |
+ // End timers |
|
4335 |
+ window.clearInterval(session.data.videoResampleInterval); |
|
4336 |
+ window.clearInterval(session.data.callTimer); |
|
4337 |
+ |
|
4338 |
+ // Add to stream |
|
4339 |
+ AddCallMessage(lineObj.BuddyObj.identity, session, reasonCode, reasonText); |
|
4340 |
+ |
|
4341 |
+ // Close up the UI |
|
4342 |
+ window.setTimeout(function () { |
|
4343 |
+ RemoveLine(lineObj); |
|
4344 |
+ }, 1000); |
|
4345 |
+ |
|
4346 |
+ UpdateBuddyList(); |
|
4347 |
+ UpdateUI(); |
|
4348 |
+ |
|
4349 |
+ // Custom Web hook |
|
4350 |
+ if(typeof web_hook_on_terminate !== 'undefined') web_hook_on_terminate(session); |
|
4351 |
+} |
|
4352 |
+ |
|
4353 |
+// Mic and Speaker Levels |
|
4354 |
+// ====================== |
|
4355 |
+function StartRemoteAudioMediaMonitoring(lineNum, session) { |
|
4356 |
+ console.log("Creating RemoteAudio AudioContext on Line:" + lineNum); |
|
4357 |
+ |
|
4358 |
+ // Create local SoundMeter |
|
4359 |
+ var soundMeter = new SoundMeter(session.id, lineNum); |
|
4360 |
+ if(soundMeter == null){ |
|
4361 |
+ console.warn("AudioContext() RemoteAudio not available... it fine."); |
|
4362 |
+ return null; |
|
4363 |
+ } |
|
4364 |
+ |
|
4365 |
+ // Ready the getStats request |
|
4366 |
+ var remoteAudioStream = new MediaStream(); |
|
4367 |
+ var audioReceiver = null; |
|
4368 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
4369 |
+ pc.getReceivers().forEach(function (RTCRtpReceiver) { |
|
4370 |
+ if(RTCRtpReceiver.track && RTCRtpReceiver.track.kind == "audio"){ |
|
4371 |
+ if(audioReceiver == null) { |
|
4372 |
+ remoteAudioStream.addTrack(RTCRtpReceiver.track); |
|
4373 |
+ audioReceiver = RTCRtpReceiver; |
|
4374 |
+ } |
|
4375 |
+ else { |
|
4376 |
+ console.log("Found another Track, but audioReceiver not null"); |
|
4377 |
+ console.log(RTCRtpReceiver); |
|
4378 |
+ console.log(RTCRtpReceiver.track); |
|
4379 |
+ } |
|
4380 |
+ } |
|
4381 |
+ }); |
|
4382 |
+ |
|
4383 |
+ // Setup Charts |
|
4384 |
+ var maxDataLength = 100; |
|
4385 |
+ soundMeter.startTime = Date.now(); |
|
4386 |
+ Chart.defaults.global.defaultFontSize = 12; |
|
4387 |
+ |
|
4388 |
+ var ChatHistoryOptions = { |
|
4389 |
+ responsive: false, |
|
4390 |
+ maintainAspectRatio: false, |
|
4391 |
+ devicePixelRatio: 1, |
|
4392 |
+ animation: false, |
|
4393 |
+ scales: { |
|
4394 |
+ yAxes: [{ |
|
4395 |
+ ticks: { beginAtZero: true } //, min: 0, max: 100 |
|
4396 |
+ }] |
|
4397 |
+ }, |
|
4398 |
+ } |
|
4399 |
+ |
|
4400 |
+ // Receive Kilobits per second |
|
4401 |
+ soundMeter.ReceiveBitRateChart = new Chart($("#line-"+ lineNum +"-AudioReceiveBitRate"), { |
|
4402 |
+ type: 'line', |
|
4403 |
+ data: { |
|
4404 |
+ labels: MakeDataArray("", maxDataLength), |
|
4405 |
+ datasets: [{ |
|
4406 |
+ label: lang.receive_kilobits_per_second, |
|
4407 |
+ data: MakeDataArray(0, maxDataLength), |
|
4408 |
+ backgroundColor: 'rgba(168, 0, 0, 0.5)', |
|
4409 |
+ borderColor: 'rgba(168, 0, 0, 1)', |
|
4410 |
+ borderWidth: 1, |
|
4411 |
+ pointRadius: 1 |
|
4412 |
+ }] |
|
4413 |
+ }, |
|
4414 |
+ options: ChatHistoryOptions |
|
4415 |
+ }); |
|
4416 |
+ soundMeter.ReceiveBitRateChart.lastValueBytesReceived = 0; |
|
4417 |
+ soundMeter.ReceiveBitRateChart.lastValueTimestamp = 0; |
|
4418 |
+ |
|
4419 |
+ // Receive Packets per second |
|
4420 |
+ soundMeter.ReceivePacketRateChart = new Chart($("#line-"+ lineNum +"-AudioReceivePacketRate"), { |
|
4421 |
+ type: 'line', |
|
4422 |
+ data: { |
|
4423 |
+ labels: MakeDataArray("", maxDataLength), |
|
4424 |
+ datasets: [{ |
|
4425 |
+ label: lang.receive_packets_per_second, |
|
4426 |
+ data: MakeDataArray(0, maxDataLength), |
|
4427 |
+ backgroundColor: 'rgba(168, 0, 0, 0.5)', |
|
4428 |
+ borderColor: 'rgba(168, 0, 0, 1)', |
|
4429 |
+ borderWidth: 1, |
|
4430 |
+ pointRadius: 1 |
|
4431 |
+ }] |
|
4432 |
+ }, |
|
4433 |
+ options: ChatHistoryOptions |
|
4434 |
+ }); |
|
4435 |
+ soundMeter.ReceivePacketRateChart.lastValuePacketReceived = 0; |
|
4436 |
+ soundMeter.ReceivePacketRateChart.lastValueTimestamp = 0; |
|
4437 |
+ |
|
4438 |
+ // Receive Packet Loss |
|
4439 |
+ soundMeter.ReceivePacketLossChart = new Chart($("#line-"+ lineNum +"-AudioReceivePacketLoss"), { |
|
4440 |
+ type: 'line', |
|
4441 |
+ data: { |
|
4442 |
+ labels: MakeDataArray("", maxDataLength), |
|
4443 |
+ datasets: [{ |
|
4444 |
+ label: lang.receive_packet_loss, |
|
4445 |
+ data: MakeDataArray(0, maxDataLength), |
|
4446 |
+ backgroundColor: 'rgba(168, 99, 0, 0.5)', |
|
4447 |
+ borderColor: 'rgba(168, 99, 0, 1)', |
|
4448 |
+ borderWidth: 1, |
|
4449 |
+ pointRadius: 1 |
|
4450 |
+ }] |
|
4451 |
+ }, |
|
4452 |
+ options: ChatHistoryOptions |
|
4453 |
+ }); |
|
4454 |
+ soundMeter.ReceivePacketLossChart.lastValuePacketLoss = 0; |
|
4455 |
+ soundMeter.ReceivePacketLossChart.lastValueTimestamp = 0; |
|
4456 |
+ |
|
4457 |
+ // Receive Jitter |
|
4458 |
+ soundMeter.ReceiveJitterChart = new Chart($("#line-"+ lineNum +"-AudioReceiveJitter"), { |
|
4459 |
+ type: 'line', |
|
4460 |
+ data: { |
|
4461 |
+ labels: MakeDataArray("", maxDataLength), |
|
4462 |
+ datasets: [{ |
|
4463 |
+ label: lang.receive_jitter, |
|
4464 |
+ data: MakeDataArray(0, maxDataLength), |
|
4465 |
+ backgroundColor: 'rgba(0, 38, 168, 0.5)', |
|
4466 |
+ borderColor: 'rgba(0, 38, 168, 1)', |
|
4467 |
+ borderWidth: 1, |
|
4468 |
+ pointRadius: 1 |
|
4469 |
+ }] |
|
4470 |
+ }, |
|
4471 |
+ options: ChatHistoryOptions |
|
4472 |
+ }); |
|
4473 |
+ |
|
4474 |
+ // Receive Audio Levels |
|
4475 |
+ soundMeter.ReceiveLevelsChart = new Chart($("#line-"+ lineNum +"-AudioReceiveLevels"), { |
|
4476 |
+ type: 'line', |
|
4477 |
+ data: { |
|
4478 |
+ labels: MakeDataArray("", maxDataLength), |
|
4479 |
+ datasets: [{ |
|
4480 |
+ label: lang.receive_audio_levels, |
|
4481 |
+ data: MakeDataArray(0, maxDataLength), |
|
4482 |
+ backgroundColor: 'rgba(140, 0, 168, 0.5)', |
|
4483 |
+ borderColor: 'rgba(140, 0, 168, 1)', |
|
4484 |
+ borderWidth: 1, |
|
4485 |
+ pointRadius: 1 |
|
4486 |
+ }] |
|
4487 |
+ }, |
|
4488 |
+ options: ChatHistoryOptions |
|
4489 |
+ }); |
|
4490 |
+ |
|
4491 |
+ // Connect to Source |
|
4492 |
+ soundMeter.connectToSource(remoteAudioStream, function (e) { |
|
4493 |
+ if (e != null) return; |
|
4494 |
+ |
|
4495 |
+ // Create remote SoundMeter |
|
4496 |
+ console.log("SoundMeter for RemoteAudio Connected, displaying levels for Line: " + lineNum); |
|
4497 |
+ soundMeter.levelsInterval = window.setInterval(function () { |
|
4498 |
+ // Calculate Levels |
|
4499 |
+ //value="0" max="1" high="0.25" (this seems low... ) |
|
4500 |
+ var level = soundMeter.instant * 4.0; |
|
4501 |
+ if (level > 1) level = 1; |
|
4502 |
+ var instPercent = level * 100; |
|
4503 |
+ |
|
4504 |
+ $("#line-" + lineNum + "-Speaker").css("height", instPercent.toFixed(2) +"%"); |
|
4505 |
+ }, 50); |
|
4506 |
+ soundMeter.networkInterval = window.setInterval(function (){ |
|
4507 |
+ // Calculate Network Conditions |
|
4508 |
+ if(audioReceiver != null) { |
|
4509 |
+ audioReceiver.getStats().then(function(stats) { |
|
4510 |
+ stats.forEach(function(report){ |
|
4511 |
+ |
|
4512 |
+ var theMoment = utcDateNow(); |
|
4513 |
+ var ReceiveBitRateChart = soundMeter.ReceiveBitRateChart; |
|
4514 |
+ var ReceivePacketRateChart = soundMeter.ReceivePacketRateChart; |
|
4515 |
+ var ReceivePacketLossChart = soundMeter.ReceivePacketLossChart; |
|
4516 |
+ var ReceiveJitterChart = soundMeter.ReceiveJitterChart; |
|
4517 |
+ var ReceiveLevelsChart = soundMeter.ReceiveLevelsChart; |
|
4518 |
+ var elapsedSec = Math.floor((Date.now() - soundMeter.startTime)/1000); |
|
4519 |
+ |
|
4520 |
+ if(report.type == "inbound-rtp"){ |
|
4521 |
+ |
|
4522 |
+ if(ReceiveBitRateChart.lastValueTimestamp == 0) { |
|
4523 |
+ ReceiveBitRateChart.lastValueTimestamp = report.timestamp; |
|
4524 |
+ ReceiveBitRateChart.lastValueBytesReceived = report.bytesReceived; |
|
4525 |
+ |
|
4526 |
+ ReceivePacketRateChart.lastValueTimestamp = report.timestamp; |
|
4527 |
+ ReceivePacketRateChart.lastValuePacketReceived = report.packetsReceived; |
|
4528 |
+ |
|
4529 |
+ ReceivePacketLossChart.lastValueTimestamp = report.timestamp; |
|
4530 |
+ ReceivePacketLossChart.lastValuePacketLoss = report.packetsLost; |
|
4531 |
+ |
|
4532 |
+ return; |
|
4533 |
+ } |
|
4534 |
+ // Receive Kilobits Per second |
|
4535 |
+ var kbitsPerSec = (8 * (report.bytesReceived - ReceiveBitRateChart.lastValueBytesReceived))/1000; |
|
4536 |
+ |
|
4537 |
+ ReceiveBitRateChart.lastValueTimestamp = report.timestamp; |
|
4538 |
+ ReceiveBitRateChart.lastValueBytesReceived = report.bytesReceived; |
|
4539 |
+ |
|
4540 |
+ soundMeter.ReceiveBitRate.push({ value: kbitsPerSec, timestamp : theMoment}); |
|
4541 |
+ ReceiveBitRateChart.data.datasets[0].data.push(kbitsPerSec); |
|
4542 |
+ ReceiveBitRateChart.data.labels.push(""); |
|
4543 |
+ if(ReceiveBitRateChart.data.datasets[0].data.length > maxDataLength) { |
|
4544 |
+ ReceiveBitRateChart.data.datasets[0].data.splice(0,1); |
|
4545 |
+ ReceiveBitRateChart.data.labels.splice(0,1); |
|
4546 |
+ } |
|
4547 |
+ ReceiveBitRateChart.update(); |
|
4548 |
+ |
|
4549 |
+ // Receive Packets Per Second |
|
4550 |
+ var PacketsPerSec = (report.packetsReceived - ReceivePacketRateChart.lastValuePacketReceived); |
|
4551 |
+ |
|
4552 |
+ ReceivePacketRateChart.lastValueTimestamp = report.timestamp; |
|
4553 |
+ ReceivePacketRateChart.lastValuePacketReceived = report.packetsReceived; |
|
4554 |
+ |
|
4555 |
+ soundMeter.ReceivePacketRate.push({ value: PacketsPerSec, timestamp : theMoment}); |
|
4556 |
+ ReceivePacketRateChart.data.datasets[0].data.push(PacketsPerSec); |
|
4557 |
+ ReceivePacketRateChart.data.labels.push(""); |
|
4558 |
+ if(ReceivePacketRateChart.data.datasets[0].data.length > maxDataLength) { |
|
4559 |
+ ReceivePacketRateChart.data.datasets[0].data.splice(0,1); |
|
4560 |
+ ReceivePacketRateChart.data.labels.splice(0,1); |
|
4561 |
+ } |
|
4562 |
+ ReceivePacketRateChart.update(); |
|
4563 |
+ |
|
4564 |
+ // Receive Packet Loss |
|
4565 |
+ var PacketsLost = (report.packetsLost - ReceivePacketLossChart.lastValuePacketLoss); |
|
4566 |
+ |
|
4567 |
+ ReceivePacketLossChart.lastValueTimestamp = report.timestamp; |
|
4568 |
+ ReceivePacketLossChart.lastValuePacketLoss = report.packetsLost; |
|
4569 |
+ |
|
4570 |
+ soundMeter.ReceivePacketLoss.push({ value: PacketsLost, timestamp : theMoment}); |
|
4571 |
+ ReceivePacketLossChart.data.datasets[0].data.push(PacketsLost); |
|
4572 |
+ ReceivePacketLossChart.data.labels.push(""); |
|
4573 |
+ if(ReceivePacketLossChart.data.datasets[0].data.length > maxDataLength) { |
|
4574 |
+ ReceivePacketLossChart.data.datasets[0].data.splice(0,1); |
|
4575 |
+ ReceivePacketLossChart.data.labels.splice(0,1); |
|
4576 |
+ } |
|
4577 |
+ ReceivePacketLossChart.update(); |
|
4578 |
+ |
|
4579 |
+ // Receive Jitter |
|
4580 |
+ soundMeter.ReceiveJitter.push({ value: report.jitter, timestamp : theMoment}); |
|
4581 |
+ ReceiveJitterChart.data.datasets[0].data.push(report.jitter); |
|
4582 |
+ ReceiveJitterChart.data.labels.push(""); |
|
4583 |
+ if(ReceiveJitterChart.data.datasets[0].data.length > maxDataLength) { |
|
4584 |
+ ReceiveJitterChart.data.datasets[0].data.splice(0,1); |
|
4585 |
+ ReceiveJitterChart.data.labels.splice(0,1); |
|
4586 |
+ } |
|
4587 |
+ ReceiveJitterChart.update(); |
|
4588 |
+ } |
|
4589 |
+ if(report.type == "track") { |
|
4590 |
+ |
|
4591 |
+ // Receive Audio Levels |
|
4592 |
+ var levelPercent = (report.audioLevel * 100); |
|
4593 |
+ soundMeter.ReceiveLevels.push({ value: levelPercent, timestamp : theMoment}); |
|
4594 |
+ ReceiveLevelsChart.data.datasets[0].data.push(levelPercent); |
|
4595 |
+ ReceiveLevelsChart.data.labels.push(""); |
|
4596 |
+ if(ReceiveLevelsChart.data.datasets[0].data.length > maxDataLength) |
|
4597 |
+ { |
|
4598 |
+ ReceiveLevelsChart.data.datasets[0].data.splice(0,1); |
|
4599 |
+ ReceiveLevelsChart.data.labels.splice(0,1); |
|
4600 |
+ } |
|
4601 |
+ ReceiveLevelsChart.update(); |
|
4602 |
+ } |
|
4603 |
+ }); |
|
4604 |
+ }); |
|
4605 |
+ } |
|
4606 |
+ } ,1000); |
|
4607 |
+ }); |
|
4608 |
+ |
|
4609 |
+ return soundMeter; |
|
4610 |
+} |
|
4611 |
+function StartLocalAudioMediaMonitoring(lineNum, session) { |
|
4612 |
+ console.log("Creating LocalAudio AudioContext on line " + lineNum); |
|
4613 |
+ |
|
4614 |
+ // Create local SoundMeter |
|
4615 |
+ var soundMeter = new SoundMeter(session.id, lineNum); |
|
4616 |
+ if(soundMeter == null){ |
|
4617 |
+ console.warn("AudioContext() LocalAudio not available... its fine.") |
|
4618 |
+ return null; |
|
4619 |
+ } |
|
4620 |
+ |
|
4621 |
+ // Ready the getStats request |
|
4622 |
+ var localAudioStream = new MediaStream(); |
|
4623 |
+ var audioSender = null; |
|
4624 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
4625 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
4626 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio"){ |
|
4627 |
+ if(audioSender == null){ |
|
4628 |
+ console.log("Adding Track to Monitor: ", RTCRtpSender.track.label); |
|
4629 |
+ localAudioStream.addTrack(RTCRtpSender.track); |
|
4630 |
+ audioSender = RTCRtpSender; |
|
4631 |
+ } |
|
4632 |
+ else { |
|
4633 |
+ console.log("Found another Track, but audioSender not null"); |
|
4634 |
+ console.log(RTCRtpSender); |
|
4635 |
+ console.log(RTCRtpSender.track); |
|
4636 |
+ } |
|
4637 |
+ } |
|
4638 |
+ }); |
|
4639 |
+ |
|
4640 |
+ // Setup Charts |
|
4641 |
+ var maxDataLength = 100; |
|
4642 |
+ soundMeter.startTime = Date.now(); |
|
4643 |
+ Chart.defaults.global.defaultFontSize = 12; |
|
4644 |
+ var ChatHistoryOptions = { |
|
4645 |
+ responsive: false, |
|
4646 |
+ maintainAspectRatio: false, |
|
4647 |
+ devicePixelRatio: 1, |
|
4648 |
+ animation: false, |
|
4649 |
+ scales: { |
|
4650 |
+ yAxes: [{ |
|
4651 |
+ ticks: { beginAtZero: true } |
|
4652 |
+ }] |
|
4653 |
+ }, |
|
4654 |
+ } |
|
4655 |
+ |
|
4656 |
+ // Send Kilobits Per Second |
|
4657 |
+ soundMeter.SendBitRateChart = new Chart($("#line-"+ lineNum +"-AudioSendBitRate"), { |
|
4658 |
+ type: 'line', |
|
4659 |
+ data: { |
|
4660 |
+ labels: MakeDataArray("", maxDataLength), |
|
4661 |
+ datasets: [{ |
|
4662 |
+ label: lang.send_kilobits_per_second, |
|
4663 |
+ data: MakeDataArray(0, maxDataLength), |
|
4664 |
+ backgroundColor: 'rgba(0, 121, 19, 0.5)', |
|
4665 |
+ borderColor: 'rgba(0, 121, 19, 1)', |
|
4666 |
+ borderWidth: 1, |
|
4667 |
+ pointRadius: 1 |
|
4668 |
+ }] |
|
4669 |
+ }, |
|
4670 |
+ options: ChatHistoryOptions |
|
4671 |
+ }); |
|
4672 |
+ soundMeter.SendBitRateChart.lastValueBytesSent = 0; |
|
4673 |
+ soundMeter.SendBitRateChart.lastValueTimestamp = 0; |
|
4674 |
+ |
|
4675 |
+ // Send Packets Per Second |
|
4676 |
+ soundMeter.SendPacketRateChart = new Chart($("#line-"+ lineNum +"-AudioSendPacketRate"), { |
|
4677 |
+ type: 'line', |
|
4678 |
+ data: { |
|
4679 |
+ labels: MakeDataArray("", maxDataLength), |
|
4680 |
+ datasets: [{ |
|
4681 |
+ label: lang.send_packets_per_second, |
|
4682 |
+ data: MakeDataArray(0, maxDataLength), |
|
4683 |
+ backgroundColor: 'rgba(0, 121, 19, 0.5)', |
|
4684 |
+ borderColor: 'rgba(0, 121, 19, 1)', |
|
4685 |
+ borderWidth: 1, |
|
4686 |
+ pointRadius: 1 |
|
4687 |
+ }] |
|
4688 |
+ }, |
|
4689 |
+ options: ChatHistoryOptions |
|
4690 |
+ }); |
|
4691 |
+ soundMeter.SendPacketRateChart.lastValuePacketSent = 0; |
|
4692 |
+ soundMeter.SendPacketRateChart.lastValueTimestamp = 0; |
|
4693 |
+ |
|
4694 |
+ // Connect to Source |
|
4695 |
+ soundMeter.connectToSource(localAudioStream, function (e) { |
|
4696 |
+ if (e != null) return; |
|
4697 |
+ |
|
4698 |
+ console.log("SoundMeter for LocalAudio Connected, displaying levels for Line: " + lineNum); |
|
4699 |
+ soundMeter.levelsInterval = window.setInterval(function () { |
|
4700 |
+ // Calculate Levels |
|
4701 |
+ //value="0" max="1" high="0.25" (this seems low... ) |
|
4702 |
+ var level = soundMeter.instant * 4.0; |
|
4703 |
+ if (level > 1) level = 1; |
|
4704 |
+ var instPercent = level * 100; |
|
4705 |
+ $("#line-" + lineNum + "-Mic").css("height", instPercent.toFixed(2) +"%"); |
|
4706 |
+ }, 50); |
|
4707 |
+ soundMeter.networkInterval = window.setInterval(function (){ |
|
4708 |
+ // Calculate Network Conditions |
|
4709 |
+ // Sending Audio Track |
|
4710 |
+ if(audioSender != null) { |
|
4711 |
+ audioSender.getStats().then(function(stats) { |
|
4712 |
+ stats.forEach(function(report){ |
|
4713 |
+ |
|
4714 |
+ var theMoment = utcDateNow(); |
|
4715 |
+ var SendBitRateChart = soundMeter.SendBitRateChart; |
|
4716 |
+ var SendPacketRateChart = soundMeter.SendPacketRateChart; |
|
4717 |
+ var elapsedSec = Math.floor((Date.now() - soundMeter.startTime)/1000); |
|
4718 |
+ |
|
4719 |
+ if(report.type == "outbound-rtp"){ |
|
4720 |
+ if(SendBitRateChart.lastValueTimestamp == 0) { |
|
4721 |
+ SendBitRateChart.lastValueTimestamp = report.timestamp; |
|
4722 |
+ SendBitRateChart.lastValueBytesSent = report.bytesSent; |
|
4723 |
+ |
|
4724 |
+ SendPacketRateChart.lastValueTimestamp = report.timestamp; |
|
4725 |
+ SendPacketRateChart.lastValuePacketSent = report.packetsSent; |
|
4726 |
+ return; |
|
4727 |
+ } |
|
4728 |
+ |
|
4729 |
+ // Send Kilobits Per second |
|
4730 |
+ var kbitsPerSec = (8 * (report.bytesSent - SendBitRateChart.lastValueBytesSent))/1000; |
|
4731 |
+ |
|
4732 |
+ SendBitRateChart.lastValueTimestamp = report.timestamp; |
|
4733 |
+ SendBitRateChart.lastValueBytesSent = report.bytesSent; |
|
4734 |
+ |
|
4735 |
+ soundMeter.SendBitRate.push({ value: kbitsPerSec, timestamp : theMoment}); |
|
4736 |
+ SendBitRateChart.data.datasets[0].data.push(kbitsPerSec); |
|
4737 |
+ SendBitRateChart.data.labels.push(""); |
|
4738 |
+ if(SendBitRateChart.data.datasets[0].data.length > maxDataLength) { |
|
4739 |
+ SendBitRateChart.data.datasets[0].data.splice(0,1); |
|
4740 |
+ SendBitRateChart.data.labels.splice(0,1); |
|
4741 |
+ } |
|
4742 |
+ SendBitRateChart.update(); |
|
4743 |
+ |
|
4744 |
+ // Send Packets Per Second |
|
4745 |
+ var PacketsPerSec = report.packetsSent - SendPacketRateChart.lastValuePacketSent; |
|
4746 |
+ |
|
4747 |
+ SendPacketRateChart.lastValueTimestamp = report.timestamp; |
|
4748 |
+ SendPacketRateChart.lastValuePacketSent = report.packetsSent; |
|
4749 |
+ |
|
4750 |
+ soundMeter.SendPacketRate.push({ value: PacketsPerSec, timestamp : theMoment}); |
|
4751 |
+ SendPacketRateChart.data.datasets[0].data.push(PacketsPerSec); |
|
4752 |
+ SendPacketRateChart.data.labels.push(""); |
|
4753 |
+ if(SendPacketRateChart.data.datasets[0].data.length > maxDataLength) { |
|
4754 |
+ SendPacketRateChart.data.datasets[0].data.splice(0,1); |
|
4755 |
+ SendPacketRateChart.data.labels.splice(0,1); |
|
4756 |
+ } |
|
4757 |
+ SendPacketRateChart.update(); |
|
4758 |
+ } |
|
4759 |
+ if(report.type == "track") { |
|
4760 |
+ // Bug/security consern... this seems always to report "0" |
|
4761 |
+ // Possible reason: When applied to isolated streams, media metrics may allow an application to infer some characteristics of the isolated stream, such as if anyone is speaking (by watching the audioLevel statistic). |
|
4762 |
+ // console.log("Audio Sender: " + report.audioLevel); |
|
4763 |
+ } |
|
4764 |
+ }); |
|
4765 |
+ }); |
|
4766 |
+ } |
|
4767 |
+ } ,1000); |
|
4768 |
+ }); |
|
4769 |
+ |
|
4770 |
+ return soundMeter; |
|
4771 |
+} |
|
4772 |
+ |
|
4773 |
+// Sounds Meter Class |
|
4774 |
+// ================== |
|
4775 |
+class SoundMeter { |
|
4776 |
+ constructor(sessionId, lineNum) { |
|
4777 |
+ var audioContext = null; |
|
4778 |
+ try { |
|
4779 |
+ window.AudioContext = window.AudioContext || window.webkitAudioContext; |
|
4780 |
+ audioContext = new AudioContext(); |
|
4781 |
+ } |
|
4782 |
+ catch(e) { |
|
4783 |
+ console.warn("AudioContext() LocalAudio not available... its fine."); |
|
4784 |
+ } |
|
4785 |
+ if (audioContext == null) return null; |
|
4786 |
+ |
|
4787 |
+ this.lineNum = lineNum; |
|
4788 |
+ this.sessionId = sessionId; |
|
4789 |
+ this.levelsInterval = null; |
|
4790 |
+ this.networkInterval = null; |
|
4791 |
+ this.startTime = 0; |
|
4792 |
+ this.ReceiveBitRateChart = null; |
|
4793 |
+ this.ReceiveBitRate = []; |
|
4794 |
+ this.ReceivePacketRateChart = null; |
|
4795 |
+ this.ReceivePacketRate = []; |
|
4796 |
+ this.ReceivePacketLossChart = null; |
|
4797 |
+ this.ReceivePacketLoss = []; |
|
4798 |
+ this.ReceiveJitterChart = null; |
|
4799 |
+ this.ReceiveJitter = []; |
|
4800 |
+ this.ReceiveLevelsChart = null; |
|
4801 |
+ this.ReceiveLevels = []; |
|
4802 |
+ this.SendBitRateChart = null; |
|
4803 |
+ this.SendBitRate = []; |
|
4804 |
+ this.SendPacketRateChart = null; |
|
4805 |
+ this.SendPacketRate = []; |
|
4806 |
+ this.context = audioContext; |
|
4807 |
+ this.instant = 0.0; |
|
4808 |
+ this.script = audioContext.createScriptProcessor(2048, 1, 1); |
|
4809 |
+ const that = this; |
|
4810 |
+ this.script.onaudioprocess = function (event) { |
|
4811 |
+ const input = event.inputBuffer.getChannelData(0); |
|
4812 |
+ let i; |
|
4813 |
+ let sum = 0.0; |
|
4814 |
+ for (i = 0; i < input.length; ++i) { |
|
4815 |
+ sum += input[i] * input[i]; |
|
4816 |
+ } |
|
4817 |
+ that.instant = Math.sqrt(sum / input.length); |
|
4818 |
+ } |
|
4819 |
+ } |
|
4820 |
+ connectToSource(stream, callback) { |
|
4821 |
+ console.log("SoundMeter connecting..."); |
|
4822 |
+ try { |
|
4823 |
+ this.mic = this.context.createMediaStreamSource(stream); |
|
4824 |
+ this.mic.connect(this.script); |
|
4825 |
+ // necessary to make sample run, but should not be. |
|
4826 |
+ this.script.connect(this.context.destination); |
|
4827 |
+ callback(null); |
|
4828 |
+ } |
|
4829 |
+ catch(e) { |
|
4830 |
+ console.error(e); // Probably not audio track |
|
4831 |
+ callback(e); |
|
4832 |
+ } |
|
4833 |
+ } |
|
4834 |
+ stop() { |
|
4835 |
+ console.log("Disconnecting SoundMeter..."); |
|
4836 |
+ try { |
|
4837 |
+ window.clearInterval(this.levelsInterval); |
|
4838 |
+ this.levelsInterval = null; |
|
4839 |
+ } |
|
4840 |
+ catch(e) { } |
|
4841 |
+ try { |
|
4842 |
+ window.clearInterval(this.networkInterval); |
|
4843 |
+ this.networkInterval = null; |
|
4844 |
+ } |
|
4845 |
+ catch(e) { } |
|
4846 |
+ this.mic.disconnect(); |
|
4847 |
+ this.script.disconnect(); |
|
4848 |
+ this.mic = null; |
|
4849 |
+ this.script = null; |
|
4850 |
+ try { |
|
4851 |
+ this.context.close(); |
|
4852 |
+ } |
|
4853 |
+ catch(e) { } |
|
4854 |
+ this.context = null; |
|
4855 |
+ |
|
4856 |
+ // Save to IndexDb |
|
4857 |
+ var lineObj = FindLineByNumber(this.lineNum); |
|
4858 |
+ var QosData = { |
|
4859 |
+ ReceiveBitRate: this.ReceiveBitRate, |
|
4860 |
+ ReceivePacketRate: this.ReceivePacketRate, |
|
4861 |
+ ReceivePacketLoss: this.ReceivePacketLoss, |
|
4862 |
+ ReceiveJitter: this.ReceiveJitter, |
|
4863 |
+ ReceiveLevels: this.ReceiveLevels, |
|
4864 |
+ SendBitRate: this.SendBitRate, |
|
4865 |
+ SendPacketRate: this.SendPacketRate, |
|
4866 |
+ } |
|
4867 |
+ SaveQosData(QosData, this.sessionId, lineObj.BuddyObj.identity); |
|
4868 |
+ } |
|
4869 |
+} |
|
4870 |
+function MeterSettingsOutput(audioStream, objectId, direction, interval){ |
|
4871 |
+ var soundMeter = new SoundMeter(null, null); |
|
4872 |
+ soundMeter.startTime = Date.now(); |
|
4873 |
+ soundMeter.connectToSource(audioStream, function (e) { |
|
4874 |
+ if (e != null) return; |
|
4875 |
+ |
|
4876 |
+ console.log("SoundMeter Connected, displaying levels to:"+ objectId); |
|
4877 |
+ soundMeter.levelsInterval = window.setInterval(function () { |
|
4878 |
+ // Calculate Levels |
|
4879 |
+ //value="0" max="1" high="0.25" (this seems low... ) |
|
4880 |
+ var level = soundMeter.instant * 4.0; |
|
4881 |
+ if (level > 1) level = 1; |
|
4882 |
+ var instPercent = level * 100; |
|
4883 |
+ |
|
4884 |
+ $("#"+objectId).css(direction, instPercent.toFixed(2) +"%"); // Settings_MicrophoneOutput "width" 50 |
|
4885 |
+ }, interval); |
|
4886 |
+ }); |
|
4887 |
+ |
|
4888 |
+ return soundMeter; |
|
4889 |
+} |
|
4890 |
+ |
|
4891 |
+// QOS |
|
4892 |
+// === |
|
4893 |
+function SaveQosData(QosData, sessionId, buddy){ |
|
4894 |
+ var indexedDB = window.indexedDB; |
|
4895 |
+ var request = indexedDB.open("CallQosData"); |
|
4896 |
+ request.onerror = function(event) { |
|
4897 |
+ console.error("IndexDB Request Error:", event); |
|
4898 |
+ } |
|
4899 |
+ request.onupgradeneeded = function(event) { |
|
4900 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
4901 |
+ var IDB = event.target.result; |
|
4902 |
+ |
|
4903 |
+ // Create Object Store |
|
4904 |
+ if(IDB.objectStoreNames.contains("CallQos") == false){ |
|
4905 |
+ var objectStore = IDB.createObjectStore("CallQos", { keyPath: "uID" }); |
|
4906 |
+ objectStore.createIndex("sessionid", "sessionid", { unique: false }); |
|
4907 |
+ objectStore.createIndex("buddy", "buddy", { unique: false }); |
|
4908 |
+ objectStore.createIndex("QosData", "QosData", { unique: false }); |
|
4909 |
+ } |
|
4910 |
+ else { |
|
4911 |
+ console.warn("IndexDB requested upgrade, but object store was in place"); |
|
4912 |
+ } |
|
4913 |
+ } |
|
4914 |
+ request.onsuccess = function(event) { |
|
4915 |
+ console.log("IndexDB connected to CallQosData"); |
|
4916 |
+ |
|
4917 |
+ var IDB = event.target.result; |
|
4918 |
+ if(IDB.objectStoreNames.contains("CallQos") == false){ |
|
4919 |
+ console.warn("IndexDB CallQosData.CallQos does not exists"); |
|
4920 |
+ return; |
|
4921 |
+ } |
|
4922 |
+ IDB.onerror = function(event) { |
|
4923 |
+ console.error("IndexDB Error:", event); |
|
4924 |
+ } |
|
4925 |
+ |
|
4926 |
+ // Prepare data to write |
|
4927 |
+ var data = { |
|
4928 |
+ uID: uID(), |
|
4929 |
+ sessionid: sessionId, |
|
4930 |
+ buddy: buddy, |
|
4931 |
+ QosData: QosData |
|
4932 |
+ } |
|
4933 |
+ // Commit Transaction |
|
4934 |
+ var transaction = IDB.transaction(["CallQos"], "readwrite"); |
|
4935 |
+ var objectStoreAdd = transaction.objectStore("CallQos").add(data); |
|
4936 |
+ objectStoreAdd.onsuccess = function(event) { |
|
4937 |
+ console.log("Call CallQos Sucess: ", sessionId); |
|
4938 |
+ } |
|
4939 |
+ } |
|
4940 |
+} |
|
4941 |
+function DisplayQosData(sessionId){ |
|
4942 |
+ var indexedDB = window.indexedDB; |
|
4943 |
+ var request = indexedDB.open("CallQosData"); |
|
4944 |
+ request.onerror = function(event) { |
|
4945 |
+ console.error("IndexDB Request Error:", event); |
|
4946 |
+ } |
|
4947 |
+ request.onupgradeneeded = function(event) { |
|
4948 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
4949 |
+ } |
|
4950 |
+ request.onsuccess = function(event) { |
|
4951 |
+ console.log("IndexDB connected to CallQosData"); |
|
4952 |
+ |
|
4953 |
+ var IDB = event.target.result; |
|
4954 |
+ if(IDB.objectStoreNames.contains("CallQos") == false){ |
|
4955 |
+ console.warn("IndexDB CallQosData.CallQos does not exists"); |
|
4956 |
+ return; |
|
4957 |
+ } |
|
4958 |
+ |
|
4959 |
+ var transaction = IDB.transaction(["CallQos"]); |
|
4960 |
+ var objectStoreGet = transaction.objectStore("CallQos").index('sessionid').getAll(sessionId); |
|
4961 |
+ objectStoreGet.onerror = function(event) { |
|
4962 |
+ console.error("IndexDB Get Error:", event); |
|
4963 |
+ } |
|
4964 |
+ objectStoreGet.onsuccess = function(event) { |
|
4965 |
+ if(event.target.result && event.target.result.length == 2){ |
|
4966 |
+ // This is the correct data |
|
4967 |
+ |
|
4968 |
+ var QosData0 = event.target.result[0].QosData; |
|
4969 |
+ // ReceiveBitRate: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] |
|
4970 |
+ // ReceiveJitter: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] |
|
4971 |
+ // ReceiveLevels: (9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] |
|
4972 |
+ // ReceivePacketLoss: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] |
|
4973 |
+ // ReceivePacketRate: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] |
|
4974 |
+ // SendBitRate: [] |
|
4975 |
+ // SendPacketRate: [] |
|
4976 |
+ var QosData1 = event.target.result[1].QosData; |
|
4977 |
+ // ReceiveBitRate: [] |
|
4978 |
+ // ReceiveJitter: [] |
|
4979 |
+ // ReceiveLevels: [] |
|
4980 |
+ // ReceivePacketLoss: [] |
|
4981 |
+ // ReceivePacketRate: [] |
|
4982 |
+ // SendBitRate: (9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] |
|
4983 |
+ // SendPacketRate: (9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] |
|
4984 |
+ |
|
4985 |
+ Chart.defaults.global.defaultFontSize = 12; |
|
4986 |
+ |
|
4987 |
+ var ChatHistoryOptions = { |
|
4988 |
+ responsive: true, |
|
4989 |
+ maintainAspectRatio: false, |
|
4990 |
+ animation: false, |
|
4991 |
+ scales: { |
|
4992 |
+ yAxes: [{ |
|
4993 |
+ ticks: { beginAtZero: true } //, min: 0, max: 100 |
|
4994 |
+ }], |
|
4995 |
+ xAxes: [{ |
|
4996 |
+ display: false |
|
4997 |
+ }] |
|
4998 |
+ }, |
|
4999 |
+ } |
|
5000 |
+ |
|
5001 |
+ // ReceiveBitRateChart |
|
5002 |
+ var labelset = []; |
|
5003 |
+ var dataset = []; |
|
5004 |
+ var data = (QosData0.ReceiveBitRate.length > 0)? QosData0.ReceiveBitRate : QosData1.ReceiveBitRate; |
|
5005 |
+ $.each(data, function(i,item){ |
|
5006 |
+ labelset.push(moment.utc(item.timestamp.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat)); |
|
5007 |
+ dataset.push(item.value); |
|
5008 |
+ }); |
|
5009 |
+ var ReceiveBitRateChart = new Chart($("#cdr-AudioReceiveBitRate"), { |
|
5010 |
+ type: 'line', |
|
5011 |
+ data: { |
|
5012 |
+ labels: labelset, |
|
5013 |
+ datasets: [{ |
|
5014 |
+ label: lang.receive_kilobits_per_second, |
|
5015 |
+ data: dataset, |
|
5016 |
+ backgroundColor: 'rgba(168, 0, 0, 0.5)', |
|
5017 |
+ borderColor: 'rgba(168, 0, 0, 1)', |
|
5018 |
+ borderWidth: 1, |
|
5019 |
+ pointRadius: 1 |
|
5020 |
+ }] |
|
5021 |
+ }, |
|
5022 |
+ options: ChatHistoryOptions |
|
5023 |
+ }); |
|
5024 |
+ |
|
5025 |
+ // ReceivePacketRateChart |
|
5026 |
+ var labelset = []; |
|
5027 |
+ var dataset = []; |
|
5028 |
+ var data = (QosData0.ReceivePacketRate.length > 0)? QosData0.ReceivePacketRate : QosData1.ReceivePacketRate; |
|
5029 |
+ $.each(data, function(i,item){ |
|
5030 |
+ labelset.push(moment.utc(item.timestamp.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat)); |
|
5031 |
+ dataset.push(item.value); |
|
5032 |
+ }); |
|
5033 |
+ var ReceivePacketRateChart = new Chart($("#cdr-AudioReceivePacketRate"), { |
|
5034 |
+ type: 'line', |
|
5035 |
+ data: { |
|
5036 |
+ labels: labelset, |
|
5037 |
+ datasets: [{ |
|
5038 |
+ label: lang.receive_packets_per_second, |
|
5039 |
+ data: dataset, |
|
5040 |
+ backgroundColor: 'rgba(168, 0, 0, 0.5)', |
|
5041 |
+ borderColor: 'rgba(168, 0, 0, 1)', |
|
5042 |
+ borderWidth: 1, |
|
5043 |
+ pointRadius: 1 |
|
5044 |
+ }] |
|
5045 |
+ }, |
|
5046 |
+ options: ChatHistoryOptions |
|
5047 |
+ }); |
|
5048 |
+ |
|
5049 |
+ // AudioReceivePacketLossChart |
|
5050 |
+ var labelset = []; |
|
5051 |
+ var dataset = []; |
|
5052 |
+ var data = (QosData0.ReceivePacketLoss.length > 0)? QosData0.ReceivePacketLoss : QosData1.ReceivePacketLoss; |
|
5053 |
+ $.each(data, function(i,item){ |
|
5054 |
+ labelset.push(moment.utc(item.timestamp.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat)); |
|
5055 |
+ dataset.push(item.value); |
|
5056 |
+ }); |
|
5057 |
+ var AudioReceivePacketLossChart = new Chart($("#cdr-AudioReceivePacketLoss"), { |
|
5058 |
+ type: 'line', |
|
5059 |
+ data: { |
|
5060 |
+ labels: labelset, |
|
5061 |
+ datasets: [{ |
|
5062 |
+ label: lang.receive_packet_loss, |
|
5063 |
+ data: dataset, |
|
5064 |
+ backgroundColor: 'rgba(168, 99, 0, 0.5)', |
|
5065 |
+ borderColor: 'rgba(168, 99, 0, 1)', |
|
5066 |
+ borderWidth: 1, |
|
5067 |
+ pointRadius: 1 |
|
5068 |
+ }] |
|
5069 |
+ }, |
|
5070 |
+ options: ChatHistoryOptions |
|
5071 |
+ }); |
|
5072 |
+ |
|
5073 |
+ // AudioReceiveJitterChart |
|
5074 |
+ var labelset = []; |
|
5075 |
+ var dataset = []; |
|
5076 |
+ var data = (QosData0.ReceiveJitter.length > 0)? QosData0.ReceiveJitter : QosData1.ReceiveJitter; |
|
5077 |
+ $.each(data, function(i,item){ |
|
5078 |
+ labelset.push(moment.utc(item.timestamp.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat)); |
|
5079 |
+ dataset.push(item.value); |
|
5080 |
+ }); |
|
5081 |
+ var AudioReceiveJitterChart = new Chart($("#cdr-AudioReceiveJitter"), { |
|
5082 |
+ type: 'line', |
|
5083 |
+ data: { |
|
5084 |
+ labels: labelset, |
|
5085 |
+ datasets: [{ |
|
5086 |
+ label: lang.receive_jitter, |
|
5087 |
+ data: dataset, |
|
5088 |
+ backgroundColor: 'rgba(0, 38, 168, 0.5)', |
|
5089 |
+ borderColor: 'rgba(0, 38, 168, 1)', |
|
5090 |
+ borderWidth: 1, |
|
5091 |
+ pointRadius: 1 |
|
5092 |
+ }] |
|
5093 |
+ }, |
|
5094 |
+ options: ChatHistoryOptions |
|
5095 |
+ }); |
|
5096 |
+ |
|
5097 |
+ // AudioReceiveLevelsChart |
|
5098 |
+ var labelset = []; |
|
5099 |
+ var dataset = []; |
|
5100 |
+ var data = (QosData0.ReceiveLevels.length > 0)? QosData0.ReceiveLevels : QosData1.ReceiveLevels; |
|
5101 |
+ $.each(data, function(i,item){ |
|
5102 |
+ labelset.push(moment.utc(item.timestamp.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat)); |
|
5103 |
+ dataset.push(item.value); |
|
5104 |
+ }); |
|
5105 |
+ var AudioReceiveLevelsChart = new Chart($("#cdr-AudioReceiveLevels"), { |
|
5106 |
+ type: 'line', |
|
5107 |
+ data: { |
|
5108 |
+ labels: labelset, |
|
5109 |
+ datasets: [{ |
|
5110 |
+ label: lang.receive_audio_levels, |
|
5111 |
+ data: dataset, |
|
5112 |
+ backgroundColor: 'rgba(140, 0, 168, 0.5)', |
|
5113 |
+ borderColor: 'rgba(140, 0, 168, 1)', |
|
5114 |
+ borderWidth: 1, |
|
5115 |
+ pointRadius: 1 |
|
5116 |
+ }] |
|
5117 |
+ }, |
|
5118 |
+ options: ChatHistoryOptions |
|
5119 |
+ }); |
|
5120 |
+ |
|
5121 |
+ // SendPacketRateChart |
|
5122 |
+ var labelset = []; |
|
5123 |
+ var dataset = []; |
|
5124 |
+ var data = (QosData0.SendPacketRate.length > 0)? QosData0.SendPacketRate : QosData1.SendPacketRate; |
|
5125 |
+ $.each(data, function(i,item){ |
|
5126 |
+ labelset.push(moment.utc(item.timestamp.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat)); |
|
5127 |
+ dataset.push(item.value); |
|
5128 |
+ }); |
|
5129 |
+ var SendPacketRateChart = new Chart($("#cdr-AudioSendPacketRate"), { |
|
5130 |
+ type: 'line', |
|
5131 |
+ data: { |
|
5132 |
+ labels: labelset, |
|
5133 |
+ datasets: [{ |
|
5134 |
+ label: lang.send_packets_per_second, |
|
5135 |
+ data: dataset, |
|
5136 |
+ backgroundColor: 'rgba(0, 121, 19, 0.5)', |
|
5137 |
+ borderColor: 'rgba(0, 121, 19, 1)', |
|
5138 |
+ borderWidth: 1, |
|
5139 |
+ pointRadius: 1 |
|
5140 |
+ }] |
|
5141 |
+ }, |
|
5142 |
+ options: ChatHistoryOptions |
|
5143 |
+ }); |
|
5144 |
+ |
|
5145 |
+ // AudioSendBitRateChart |
|
5146 |
+ var labelset = []; |
|
5147 |
+ var dataset = []; |
|
5148 |
+ var data = (QosData0.SendBitRate.length > 0)? QosData0.SendBitRate : QosData1.SendBitRate; |
|
5149 |
+ $.each(data, function(i,item){ |
|
5150 |
+ labelset.push(moment.utc(item.timestamp.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat)); |
|
5151 |
+ dataset.push(item.value); |
|
5152 |
+ }); |
|
5153 |
+ var AudioSendBitRateChart = new Chart($("#cdr-AudioSendBitRate"), { |
|
5154 |
+ type: 'line', |
|
5155 |
+ data: { |
|
5156 |
+ labels: labelset, |
|
5157 |
+ datasets: [{ |
|
5158 |
+ label: lang.send_kilobits_per_second, |
|
5159 |
+ data: dataset, |
|
5160 |
+ backgroundColor: 'rgba(0, 121, 19, 0.5)', |
|
5161 |
+ borderColor: 'rgba(0, 121, 19, 1)', |
|
5162 |
+ borderWidth: 1, |
|
5163 |
+ pointRadius: 1 |
|
5164 |
+ }] |
|
5165 |
+ }, |
|
5166 |
+ options: ChatHistoryOptions |
|
5167 |
+ }); |
|
5168 |
+ } else { |
|
5169 |
+ console.warn("Result not expected", event.target.result); |
|
5170 |
+ } |
|
5171 |
+ } |
|
5172 |
+ } |
|
5173 |
+} |
|
5174 |
+function DeleteQosData(buddy){ |
|
5175 |
+ var indexedDB = window.indexedDB; |
|
5176 |
+ var request = indexedDB.open("CallQosData"); |
|
5177 |
+ request.onerror = function(event) { |
|
5178 |
+ console.error("IndexDB Request Error:", event); |
|
5179 |
+ } |
|
5180 |
+ request.onupgradeneeded = function(event) { |
|
5181 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
5182 |
+ // If this is the case, there will be no call recordings |
|
5183 |
+ } |
|
5184 |
+ request.onsuccess = function(event) { |
|
5185 |
+ console.log("IndexDB connected to CallQosData"); |
|
5186 |
+ |
|
5187 |
+ var IDB = event.target.result; |
|
5188 |
+ if(IDB.objectStoreNames.contains("CallQos") == false){ |
|
5189 |
+ console.warn("IndexDB CallQosData.CallQos does not exists"); |
|
5190 |
+ return; |
|
5191 |
+ } |
|
5192 |
+ IDB.onerror = function(event) { |
|
5193 |
+ console.error("IndexDB Error:", event); |
|
5194 |
+ } |
|
5195 |
+ |
|
5196 |
+ // Loop and Delete |
|
5197 |
+ console.log("Deleting CallQosData: ", buddy); |
|
5198 |
+ var transaction = IDB.transaction(["CallQos"], "readwrite"); |
|
5199 |
+ var objectStore = transaction.objectStore("CallQos"); |
|
5200 |
+ var objectStoreGet = objectStore.index('buddy').getAll(buddy); |
|
5201 |
+ |
|
5202 |
+ objectStoreGet.onerror = function(event) { |
|
5203 |
+ console.error("IndexDB Get Error:", event); |
|
5204 |
+ } |
|
5205 |
+ objectStoreGet.onsuccess = function(event) { |
|
5206 |
+ if(event.target.result && event.target.result.length > 0){ |
|
5207 |
+ // There sre some rows to delete |
|
5208 |
+ $.each(event.target.result, function(i, item){ |
|
5209 |
+ // console.log("Delete: ", item.uID); |
|
5210 |
+ try{ |
|
5211 |
+ objectStore.delete(item.uID); |
|
5212 |
+ } catch(e){ |
|
5213 |
+ console.log("Call CallQosData Delete failed: ", e); |
|
5214 |
+ } |
|
5215 |
+ }); |
|
5216 |
+ } |
|
5217 |
+ } |
|
5218 |
+ |
|
5219 |
+ } |
|
5220 |
+} |
|
5221 |
+ |
|
5222 |
+// Presence / Subscribe |
|
5223 |
+// ==================== |
|
5224 |
+function SubscribeAll() { |
|
5225 |
+ console.log("Subscribe to voicemail Messages..."); |
|
5226 |
+ |
|
5227 |
+ // conference, message-summary, dialog, presence, presence.winfo, xcap-diff, dialog.winfo, refer |
|
5228 |
+ |
|
5229 |
+ // Voicemail notice |
|
5230 |
+ var vmOptions = { expires: 300 } |
|
5231 |
+ voicemailSubs = userAgent.subscribe(SipUsername + "@" + wssServer, 'message-summary', vmOptions); // message-summary = voicemail messages |
|
5232 |
+ voicemailSubs.on('notify', function (notification) { |
|
5233 |
+ |
|
5234 |
+ // You have voicemail: |
|
5235 |
+ // Message-Account: sip:alice@example.com |
|
5236 |
+ // Messages-Waiting: no |
|
5237 |
+ // Fax-Message: 2/4 |
|
5238 |
+ // Voice-Message: 0/0 (0/0) <-- new/old (new & urgent/ old & urgent) |
|
5239 |
+ |
|
5240 |
+ var messagesWaitng = false; |
|
5241 |
+ $.each(notification.request.body.split("\n"), function (i, line) { |
|
5242 |
+ if(line.indexOf("Messages-Waiting:") != -1){ |
|
5243 |
+ messagesWaitng = ($.trim(line.replace("Messages-Waiting:", "")) == "yes"); |
|
5244 |
+ } |
|
5245 |
+ }); |
|
5246 |
+ |
|
5247 |
+ if(messagesWaitng){ |
|
5248 |
+ // Notify user of voicemail |
|
5249 |
+ console.log("You have voicemail!"); |
|
5250 |
+ } |
|
5251 |
+ }); |
|
5252 |
+ |
|
5253 |
+ // Dialog Subscription (This version isnt as nice as PIDF) |
|
5254 |
+ // var dialogOptions = { expires: 300, extraHeaders: ['Accept: application/dialog-info+xml'] } |
|
5255 |
+ |
|
5256 |
+ // PIDF Subscription |
|
5257 |
+ var dialogOptions = { expires: 300, extraHeaders: ['Accept: application/pidf+xml'] } |
|
5258 |
+ // var dialogOptions = { expires: 300, extraHeaders: ['Accept: application/pidf+xml', 'application/xpidf+xml', 'application/simple-message-summary', 'application/im-iscomposing+xml'] } |
|
5259 |
+ |
|
5260 |
+ // Start subscribe all |
|
5261 |
+ console.log("Starting Subscribe of all ("+ Buddies.length +") Extension Buddies..."); |
|
5262 |
+ for(var b=0; b<Buddies.length; b++) { |
|
5263 |
+ var buddyObj = Buddies[b]; |
|
5264 |
+ if(buddyObj.type == "extension") { |
|
5265 |
+ console.log("SUBSCRIBE: "+ buddyObj.ExtNo +"@" + wssServer); |
|
5266 |
+ var blfObj = userAgent.subscribe(buddyObj.ExtNo +"@" + wssServer, 'presence', dialogOptions); |
|
5267 |
+ blfObj.data.buddyId = buddyObj.identity; |
|
5268 |
+ blfObj.on('notify', function (notification) { |
|
5269 |
+ RecieveBlf(notification); |
|
5270 |
+ }); |
|
5271 |
+ BlfSubs.push(blfObj); |
|
5272 |
+ } |
|
5273 |
+ } |
|
5274 |
+} |
|
5275 |
+function SubscribeBuddy(buddyObj) { |
|
5276 |
+ var dialogOptions = { expires: 300, extraHeaders: ['Accept: application/pidf+xml'] } |
|
5277 |
+ |
|
5278 |
+ if(buddyObj.type == "extension") { |
|
5279 |
+ console.log("SUBSCRIBE: "+ buddyObj.ExtNo +"@" + wssServer); |
|
5280 |
+ var blfObj = userAgent.subscribe(buddyObj.ExtNo +"@" + wssServer, 'presence', dialogOptions); |
|
5281 |
+ blfObj.data.buddyId = buddyObj.identity; |
|
5282 |
+ blfObj.on('notify', function (notification) { |
|
5283 |
+ RecieveBlf(notification); |
|
5284 |
+ }); |
|
5285 |
+ BlfSubs.push(blfObj); |
|
5286 |
+ } |
|
5287 |
+} |
|
5288 |
+function RecieveBlf(notification) { |
|
5289 |
+ if (userAgent == null || !userAgent.isRegistered()) return; |
|
5290 |
+ |
|
5291 |
+ var ContentType = notification.request.headers["Content-Type"][0].parsed; |
|
5292 |
+ if (ContentType == "application/pidf+xml") { |
|
5293 |
+ |
|
5294 |
+ var xml = $($.parseXML(notification.request.body)); |
|
5295 |
+ |
|
5296 |
+ var Entity = xml.find("presence").attr("entity"); |
|
5297 |
+ var Contact = xml.find("presence").find("tuple").find("contact").text(); |
|
5298 |
+ if (SipUsername == Entity.split("@")[0].split(":")[1] || SipUsername == Contact.split("@")[0].split(":")[1]){ |
|
5299 |
+ // Message is for you. |
|
5300 |
+ } |
|
5301 |
+ else { |
|
5302 |
+ console.warn("presence message not for you.", xml); |
|
5303 |
+ return; |
|
5304 |
+ } |
|
5305 |
+ |
|
5306 |
+ var buddy = xml.find("presence").find("tuple").attr("id"); |
|
5307 |
+ |
|
5308 |
+ var statusObj = xml.find("presence").find("tuple").find("status"); |
|
5309 |
+ var availability = xml.find("presence").find("tuple").find("status").find("basic").text(); |
|
5310 |
+ var friendlyState = xml.find("presence").find("note").text(); |
|
5311 |
+ var dotClass = "dotOffline"; |
|
5312 |
+ |
|
5313 |
+ if (friendlyState == "Not online") dotClass = "dotOffline"; |
|
5314 |
+ if (friendlyState == "Ready") dotClass = "dotOnline"; |
|
5315 |
+ if (friendlyState == "On the phone") dotClass = "dotInUse"; |
|
5316 |
+ if (friendlyState == "Ringing") dotClass = "dotRinging"; |
|
5317 |
+ if (friendlyState == "On hold") dotClass = "dotOnHold"; |
|
5318 |
+ if (friendlyState == "Unavailable") dotClass = "dotOffline"; |
|
5319 |
+ |
|
5320 |
+ // dotOnline | dotOffline | dotRinging | dotInUse | dotReady | dotOnHold |
|
5321 |
+ var buddyObj = FindBuddyByExtNo(buddy); |
|
5322 |
+ if(buddyObj != null) |
|
5323 |
+ { |
|
5324 |
+ console.log("Setting Presence for "+ buddyObj.identity +" to "+ friendlyState); |
|
5325 |
+ $("#contact-" + buddyObj.identity + "-devstate").prop("class", dotClass); |
|
5326 |
+ $("#contact-" + buddyObj.identity + "-devstate-main").prop("class", dotClass); |
|
5327 |
+ buddyObj.devState = dotClass; |
|
5328 |
+ buddyObj.presence = friendlyState; |
|
5329 |
+ |
|
5330 |
+ if (friendlyState == "Not online") friendlyState = lang.state_not_online; |
|
5331 |
+ if (friendlyState == "Ready") friendlyState = lang.state_ready; |
|
5332 |
+ if (friendlyState == "On the phone") friendlyState = lang.state_on_the_phone; |
|
5333 |
+ if (friendlyState == "Ringing") friendlyState = lang.state_ringing; |
|
5334 |
+ if (friendlyState == "On hold") friendlyState = lang.state_on_hold; |
|
5335 |
+ if (friendlyState == "Unavailable") friendlyState = lang.state_unavailable; |
|
5336 |
+ $("#contact-" + buddyObj.identity + "-presence").html(friendlyState); |
|
5337 |
+ $("#contact-" + buddyObj.identity + "-presence-main").html(friendlyState); |
|
5338 |
+ } |
|
5339 |
+ } |
|
5340 |
+ else if (ContentType == "application/dialog-info+xml") |
|
5341 |
+ { |
|
5342 |
+ // Handle "Dialog" State |
|
5343 |
+ |
|
5344 |
+ var xml = $($.parseXML(notification.request.body)); |
|
5345 |
+ |
|
5346 |
+ var ObservedUser = xml.find("dialog-info").attr("entity"); |
|
5347 |
+ var buddy = ObservedUser.split("@")[0].split(":")[1]; |
|
5348 |
+ |
|
5349 |
+ var version = xml.find("dialog-info").attr("version"); |
|
5350 |
+ |
|
5351 |
+ var DialogState = xml.find("dialog-info").attr("state"); |
|
5352 |
+ if (DialogState != "full") return; |
|
5353 |
+ |
|
5354 |
+ var extId = xml.find("dialog-info").find("dialog").attr("id"); |
|
5355 |
+ if (extId != buddy) return; |
|
5356 |
+ |
|
5357 |
+ var state = xml.find("dialog-info").find("dialog").find("state").text(); |
|
5358 |
+ var friendlyState = "Unknown"; |
|
5359 |
+ if (state == "terminated") friendlyState = "Ready"; |
|
5360 |
+ if (state == "trying") friendlyState = "On the phone"; |
|
5361 |
+ if (state == "proceeding") friendlyState = "On the phone"; |
|
5362 |
+ if (state == "early") friendlyState = "Ringing"; |
|
5363 |
+ if (state == "confirmed") friendlyState = "On the phone"; |
|
5364 |
+ |
|
5365 |
+ var dotClass = "dotOffline"; |
|
5366 |
+ if (friendlyState == "Not online") dotClass = "dotOffline"; |
|
5367 |
+ if (friendlyState == "Ready") dotClass = "dotOnline"; |
|
5368 |
+ if (friendlyState == "On the phone") dotClass = "dotInUse"; |
|
5369 |
+ if (friendlyState == "Ringing") dotClass = "dotRinging"; |
|
5370 |
+ if (friendlyState == "On hold") dotClass = "dotOnHold"; |
|
5371 |
+ if (friendlyState == "Unavailable") dotClass = "dotOffline"; |
|
5372 |
+ |
|
5373 |
+ // The dialog states only report devices states, and cant say online or offline. |
|
5374 |
+ // dotOnline | dotOffline | dotRinging | dotInUse | dotReady | dotOnHold |
|
5375 |
+ var buddyObj = FindBuddyByExtNo(buddy); |
|
5376 |
+ if(buddyObj != null) |
|
5377 |
+ { |
|
5378 |
+ console.log("Setting Presence for "+ buddyObj.identity +" to "+ friendlyState); |
|
5379 |
+ $("#contact-" + buddyObj.identity + "-devstate").prop("class", dotClass); |
|
5380 |
+ $("#contact-" + buddyObj.identity + "-devstate-main").prop("class", dotClass); |
|
5381 |
+ buddyObj.devState = dotClass; |
|
5382 |
+ buddyObj.presence = friendlyState; |
|
5383 |
+ |
|
5384 |
+ if (friendlyState == "Unknown") friendlyState = lang.state_unknown; |
|
5385 |
+ if (friendlyState == "Not online") friendlyState = lang.state_not_online; |
|
5386 |
+ if (friendlyState == "Ready") friendlyState = lang.state_ready; |
|
5387 |
+ if (friendlyState == "On the phone") friendlyState = lang.state_on_the_phone; |
|
5388 |
+ if (friendlyState == "Ringing") friendlyState = lang.state_ringing; |
|
5389 |
+ if (friendlyState == "On hold") friendlyState = lang.state_on_hold; |
|
5390 |
+ if (friendlyState == "Unavailable") friendlyState = lang.state_unavailable; |
|
5391 |
+ $("#contact-" + buddyObj.identity + "-presence").html(friendlyState); |
|
5392 |
+ $("#contact-" + buddyObj.identity + "-presence-main").html(friendlyState); |
|
5393 |
+ } |
|
5394 |
+ } |
|
5395 |
+} |
|
5396 |
+function UnsubscribeAll() { |
|
5397 |
+ console.log("Unsubscribing "+ BlfSubs.length + " subscriptions..."); |
|
5398 |
+ for (var blf = 0; blf < BlfSubs.length; blf++) { |
|
5399 |
+ BlfSubs[blf].unsubscribe(); |
|
5400 |
+ BlfSubs[blf].close(); |
|
5401 |
+ } |
|
5402 |
+ BlfSubs = new Array(); |
|
5403 |
+ |
|
5404 |
+ for(var b=0; b<Buddies.length; b++) { |
|
5405 |
+ var buddyObj = Buddies[b]; |
|
5406 |
+ if(buddyObj.type == "extension") { |
|
5407 |
+ $("#contact-" + buddyObj.identity + "-devstate").prop("class", "dotOffline"); |
|
5408 |
+ $("#contact-" + buddyObj.identity + "-devstate-main").prop("class", "dotOffline"); |
|
5409 |
+ $("#contact-" + buddyObj.identity + "-presence").html(lang.state_unknown); |
|
5410 |
+ $("#contact-" + buddyObj.identity + "-presence-main").html(lang.state_unknown); |
|
5411 |
+ } |
|
5412 |
+ } |
|
5413 |
+} |
|
5414 |
+function UnsubscribeBuddy(buddyObj) { |
|
5415 |
+ if(buddyObj.type != "extension") return; |
|
5416 |
+ |
|
5417 |
+ for (var blf = 0; blf < BlfSubs.length; blf++) { |
|
5418 |
+ var blfObj = BlfSubs[blf]; |
|
5419 |
+ if(blfObj.data.buddyId == buddyObj.identity){ |
|
5420 |
+ console.log("Unsubscribing:", buddyObj.identity); |
|
5421 |
+ if(blfObj.dialog != null){ |
|
5422 |
+ blfObj.unsubscribe(); |
|
5423 |
+ blfObj.close(); |
|
5424 |
+ } |
|
5425 |
+ BlfSubs.splice(blf, 1); |
|
5426 |
+ break; |
|
5427 |
+ } |
|
5428 |
+ } |
|
5429 |
+} |
|
5430 |
+ |
|
5431 |
+// Buddy: Chat / Instant Message / XMPP |
|
5432 |
+// ==================================== |
|
5433 |
+function InitinaliseStream(buddy){ |
|
5434 |
+ var template = { TotalRows:0, DataCollection:[] } |
|
5435 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(template)); |
|
5436 |
+ return JSON.parse(localDB.getItem(buddy + "-stream")); |
|
5437 |
+} |
|
5438 |
+function splitString(str, size) { |
|
5439 |
+ const mPieces = Math.ceil(str.length / size); |
|
5440 |
+ const piecesArr = []; |
|
5441 |
+ |
|
5442 |
+ for (let i = 0, s = 0; i < mPieces; ++i, s += size) { |
|
5443 |
+ piecesArr[i] = str.substr(s, size); |
|
5444 |
+ } |
|
5445 |
+ return piecesArr; |
|
5446 |
+} |
|
5447 |
+function generateAESKey(passphrase) { |
|
5448 |
+ const salt = CryptoJS.lib.WordArray.random(128 / 8); |
|
5449 |
+ const key256Bits = CryptoJS.PBKDF2(passphrase, salt, { |
|
5450 |
+ keySize: 256 / 32, |
|
5451 |
+ iterations: 100, |
|
5452 |
+ }); |
|
5453 |
+ return key256Bits; |
|
5454 |
+} |
|
5455 |
+function encryptAES(message, key) { |
|
5456 |
+ var message = CryptoJS.AES.encrypt(message, key); |
|
5457 |
+ return message.toString(); |
|
5458 |
+} |
|
5459 |
+function decryptAES(message, key) { |
|
5460 |
+ var code = CryptoJS.AES.decrypt(message, key); |
|
5461 |
+ var decryptedMessage = code.toString(CryptoJS.enc.Utf8); |
|
5462 |
+ return decryptedMessage; |
|
5463 |
+} |
|
5464 |
+function getChatRSAPubKey(recsendSIPuser) { |
|
5465 |
+ var chatPubKey = ''; |
|
5466 |
+ $.ajax({ |
|
5467 |
+ 'async': false, |
|
5468 |
+ 'global': false, |
|
5469 |
+ type: "POST", |
|
5470 |
+ url: "get-text-chat-pub-key.php", |
|
5471 |
+ dataType: "JSON", |
|
5472 |
+ data: { |
|
5473 |
+ recsendsipuser: recsendSIPuser, |
|
5474 |
+ s_ajax_call: validateSToken |
|
5475 |
+ }, |
|
5476 |
+ success: function(result) { |
|
5477 |
+ if (result.resmessage == 'success') { |
|
5478 |
+ chatPubKey = "`" + result.chatkey.join("") + "`"; |
|
5479 |
+ } else { |
|
5480 |
+ pubKeyCheck = 1; |
|
5481 |
+ alert('An error occurred while retrieving the public key for text chat!'); |
|
5482 |
+ } |
|
5483 |
+ }, |
|
5484 |
+ error: function(result) { |
|
5485 |
+ alert('An error occurred while attempting to retrieve the public key for text chat!'); |
|
5486 |
+ } |
|
5487 |
+ }); |
|
5488 |
+ return chatPubKey; |
|
5489 |
+} |
|
5490 |
+ |
|
5491 |
+function SendChatMessage(buddy) { |
|
5492 |
+ |
|
5493 |
+ if (userAgent == null) return; |
|
5494 |
+ if (!userAgent.isRegistered()) return; |
|
5495 |
+ |
|
5496 |
+ var messageraw = $("#contact-" + buddy + "-ChatMessage").val(); |
|
5497 |
+ messagetrim = $.trim(messageraw); |
|
5498 |
+ |
|
5499 |
+ if (messagetrim == "" && (sendFileCheck == 0 || (sendFileCheck == 1 && $("#selectedFile").val() == ""))) { |
|
5500 |
+ Alert(lang.alert_empty_text_message, lang.no_message); |
|
5501 |
+ return; |
|
5502 |
+ } |
|
5503 |
+ |
|
5504 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
5505 |
+ |
|
5506 |
+ if ($.inArray(buddyObj.presence, ["Ready", "On the phone", "Ringing", "On hold"]) == -1) { |
|
5507 |
+ alert("You cannot send a message or a file to a contact who is not online!"); |
|
5508 |
+ $("#sendFileLoader").remove(); |
|
5509 |
+ $("#selectedFile").val(""); |
|
5510 |
+ $("#sendFileFormChat").remove(); |
|
5511 |
+ sendFileCheck = 0; |
|
5512 |
+ return; |
|
5513 |
+ } |
|
5514 |
+ |
|
5515 |
+ var genPassphr = Date.now() + Math.floor(Math.random()*10000).toString(6).toUpperCase(); |
|
5516 |
+ var aesKey = String(generateAESKey(genPassphr)); |
|
5517 |
+ var encryptedMes = encryptAES(messagetrim, aesKey); |
|
5518 |
+ |
|
5519 |
+ // Split the encrypted message into smaller pieces to fit the 1024 byte limit for SIP messages, which is hard-coded in Asterisk |
|
5520 |
+ var messageprearr = []; |
|
5521 |
+ var messageprearr = splitString(encryptedMes, 900); |
|
5522 |
+ |
|
5523 |
+ var genMessageId = Date.now() + Math.floor(Math.random()*10000).toString(16).toUpperCase(); |
|
5524 |
+ var messageIdent = genMessageId + profileUser; |
|
5525 |
+ var firstPieceCheck = []; |
|
5526 |
+ firstPieceCheck = [messageIdent, 1]; |
|
5527 |
+ var lastPieceCheck = []; |
|
5528 |
+ lastPieceCheck = [messageIdent, 0]; |
|
5529 |
+ |
|
5530 |
+ // Get the public key of the extension to which we send the message |
|
5531 |
+ var destExtChatRSAPubKey = getChatRSAPubKey(buddyObj.ExtNo); |
|
5532 |
+ |
|
5533 |
+ // Encrypt the AES key with RSA |
|
5534 |
+ var newencrypt = new JSEncrypt(); |
|
5535 |
+ newencrypt.setPublicKey(destExtChatRSAPubKey); |
|
5536 |
+ var encmIdAesKey = newencrypt.encrypt(aesKey); |
|
5537 |
+ |
|
5538 |
+ // Add the encrypted AES key as the first element of the array of message pieces |
|
5539 |
+ messageprearr.unshift(encmIdAesKey); |
|
5540 |
+ |
|
5541 |
+ $("#contact-"+ buddy +"-ChatHistory").after("<span id='sendFileLoader'></span>"); |
|
5542 |
+ |
|
5543 |
+ for (var k = 0; k < messageprearr.length; k++) { |
|
5544 |
+ |
|
5545 |
+ if (k == 0) { |
|
5546 |
+ // Send the RSA-encrypted AES key as first piece of the message |
|
5547 |
+ var messagePiece = messageIdent + "|" + messageprearr.length + "|" + parseInt(k) + "||" + messageprearr[k]; |
|
5548 |
+ } else if (sendFileCheck == 0 && messageprearr[k] != '') { |
|
5549 |
+ var messagePiece = messageIdent + "|" + messageprearr.length + "|" + parseInt(k) + "||" + messageprearr[k]; |
|
5550 |
+ } else if (sendFileCheck == 1 && sendFileChatErr == '') { |
|
5551 |
+ var messagePiece = messageIdent + "|" + messageprearr.length + "|" + parseInt(k) + "|" + upFileName + "|" + messageprearr[k]; |
|
5552 |
+ } else if (sendFileCheck == 1 && sendFileChatErr != '') { |
|
5553 |
+ $("#sendFileFormChat").remove(); |
|
5554 |
+ sendFileChatErr = ''; |
|
5555 |
+ sendFileCheck = 0; |
|
5556 |
+ return; |
|
5557 |
+ } |
|
5558 |
+ |
|
5559 |
+ if (k == 1) { firstPieceCheck = [messageIdent, 0]; } |
|
5560 |
+ |
|
5561 |
+ if (k == (messageprearr.length - 1)) { lastPieceCheck = [messageIdent, 1]; } |
|
5562 |
+ |
|
5563 |
+ SendChatMessageProc(buddy, buddyObj, messageIdent, messagePiece, messagetrim, firstPieceCheck, lastPieceCheck); |
|
5564 |
+ } |
|
5565 |
+} |
|
5566 |
+ |
|
5567 |
+function SendChatMessageProc(buddy, buddyObj, messageIdent, messagePiece, messagetrim, firstPieceCheck, lastPieceCheck) { |
|
5568 |
+ |
|
5569 |
+ var messageId = uID(); |
|
5570 |
+ |
|
5571 |
+ if (pubKeyCheck == 1) { pubKeyCheck = 0; $("#selectedFile").val(""); $("#sendFileLoader").remove(); return; } |
|
5572 |
+ |
|
5573 |
+ sendFileChatErr = ''; |
|
5574 |
+ |
|
5575 |
+ $("#sendFileFormChat").on('submit', function(ev) { |
|
5576 |
+ ev.preventDefault(); |
|
5577 |
+ |
|
5578 |
+ $.ajax({ |
|
5579 |
+ 'async': false, |
|
5580 |
+ 'global': false, |
|
5581 |
+ type: 'POST', |
|
5582 |
+ url: 'text-chat-upload-file.php', |
|
5583 |
+ data: new FormData(this), |
|
5584 |
+ dataType: "JSON", |
|
5585 |
+ contentType: false, |
|
5586 |
+ cache: false, |
|
5587 |
+ processData:false, |
|
5588 |
+ success: function(respdata) { |
|
5589 |
+ if (respdata.error != '') { |
|
5590 |
+ sendFileChatErr = respdata.error; |
|
5591 |
+ $("#sendFileFormChat").remove(); |
|
5592 |
+ $("#sendFileLoader").remove(); |
|
5593 |
+ alert("Error: " + respdata.error); |
|
5594 |
+ } |
|
5595 |
+ }, |
|
5596 |
+ error: function(respdata) { |
|
5597 |
+ alert("An error occurred while sending the file!"); |
|
5598 |
+ } |
|
5599 |
+ }); |
|
5600 |
+ }); |
|
5601 |
+ |
|
5602 |
+ if (sendFileCheck == 1 && (firstPieceCheck[0] == messageIdent && firstPieceCheck[1] == 1)) { |
|
5603 |
+ $("#submitFileChat").click(); |
|
5604 |
+ } |
|
5605 |
+ |
|
5606 |
+ if (lastPieceCheck[0] == messageIdent && lastPieceCheck[1] == 1 && sendFileCheck == 1 && sendFileChatErr != '') { |
|
5607 |
+ $("#sendFileFormChat").remove(); |
|
5608 |
+ $("#sendFileLoader").remove(); |
|
5609 |
+ sendFileChatErr = ''; |
|
5610 |
+ sendFileCheck = 0; |
|
5611 |
+ return; |
|
5612 |
+ } |
|
5613 |
+ |
|
5614 |
+ if (buddyObj.type == "extension" || buddyObj.type == "group") { |
|
5615 |
+ |
|
5616 |
+ var chatBuddy = buddyObj.ExtNo + "@" + wssServer; |
|
5617 |
+ console.log("MESSAGE: "+ chatBuddy + " (extension)"); |
|
5618 |
+ |
|
5619 |
+ var messageObj = userAgent.message(chatBuddy, messagePiece); |
|
5620 |
+ |
|
5621 |
+ messageObj.data.direction = "outbound"; |
|
5622 |
+ messageObj.data.messageId = messageId; |
|
5623 |
+ |
|
5624 |
+ messageObj.on("accepted", function (response, cause){ |
|
5625 |
+ |
|
5626 |
+ if(response.status_code == 202) { |
|
5627 |
+ console.log("Message Accepted:", messageId); |
|
5628 |
+ |
|
5629 |
+ // Update DB |
|
5630 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
5631 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
5632 |
+ $.each(currentStream.DataCollection, function (i, item) { |
|
5633 |
+ if (item.ItemType == "MSG" && item.ItemId == messageId) { |
|
5634 |
+ // Found |
|
5635 |
+ item.Sent = true; |
|
5636 |
+ return false; |
|
5637 |
+ } |
|
5638 |
+ }); |
|
5639 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
5640 |
+ |
|
5641 |
+ RefreshStream(buddyObj); |
|
5642 |
+ } |
|
5643 |
+ } else { |
|
5644 |
+ console.warn("Message Error", response.status_code, cause); |
|
5645 |
+ |
|
5646 |
+ // Update DB |
|
5647 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
5648 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
5649 |
+ $.each(currentStream.DataCollection, function (i, item) { |
|
5650 |
+ if (item.ItemType == "MSG" && item.ItemId == messageId) { |
|
5651 |
+ // Found |
|
5652 |
+ item.Sent = false; |
|
5653 |
+ return false; |
|
5654 |
+ } |
|
5655 |
+ }); |
|
5656 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
5657 |
+ |
|
5658 |
+ RefreshStream(buddyObj); |
|
5659 |
+ } |
|
5660 |
+ } |
|
5661 |
+ }); |
|
5662 |
+ |
|
5663 |
+ // Custom Web hook |
|
5664 |
+ if (typeof web_hook_on_message !== 'undefined') web_hook_on_message(messageObj); |
|
5665 |
+ } |
|
5666 |
+ |
|
5667 |
+ if (lastPieceCheck[0] == messageIdent && lastPieceCheck[1] == 1) { |
|
5668 |
+ |
|
5669 |
+ // Update Stream |
|
5670 |
+ var DateTime = moment.utc().format("YYYY-MM-DD HH:mm:ss UTC"); |
|
5671 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
5672 |
+ if(currentStream == null) currentStream = InitinaliseStream(buddy); |
|
5673 |
+ |
|
5674 |
+ // Add New Message |
|
5675 |
+ var newMessageJson = { |
|
5676 |
+ ItemId: messageId, |
|
5677 |
+ ItemType: "MSG", |
|
5678 |
+ ItemDate: DateTime, |
|
5679 |
+ SrcUserId: profileUserID, |
|
5680 |
+ Src: "\""+ profileName +"\" <"+ profileUser +">", |
|
5681 |
+ DstUserId: buddy, |
|
5682 |
+ Dst: "", |
|
5683 |
+ MessageData: messagetrim |
|
5684 |
+ } |
|
5685 |
+ |
|
5686 |
+ // If a file is sent, add the sent file section |
|
5687 |
+ if (sendFileCheck == 1) { |
|
5688 |
+ |
|
5689 |
+ $("#sendFileFormChat").remove(); |
|
5690 |
+ sendFileCheck = 0; |
|
5691 |
+ |
|
5692 |
+ var newMessageId = uID(); |
|
5693 |
+ var newDateTime = moment.utc().format("YYYY-MM-DD HH:mm:ss UTC"); |
|
5694 |
+ |
|
5695 |
+ var newFileMessageJson = { |
|
5696 |
+ ItemId: newMessageId, |
|
5697 |
+ ItemType: "FILE", |
|
5698 |
+ ItemDate: newDateTime, |
|
5699 |
+ SrcUserId: profileUserID, |
|
5700 |
+ Src: "\""+ profileName +"\" <"+ profileUser +">", |
|
5701 |
+ DstUserId: buddy, |
|
5702 |
+ Dst: buddyObj.ExtNo, |
|
5703 |
+ SentFileName: upFileName, |
|
5704 |
+ MessageData: "Download file" |
|
5705 |
+ } |
|
5706 |
+ |
|
5707 |
+ if (sendFileChatErr == '') { |
|
5708 |
+ currentStream.DataCollection.push(newFileMessageJson); |
|
5709 |
+ } |
|
5710 |
+ |
|
5711 |
+ } else { $("#sendFileFormChat").remove(); } |
|
5712 |
+ |
|
5713 |
+ currentStream.DataCollection.push(newMessageJson); |
|
5714 |
+ |
|
5715 |
+ currentStream.TotalRows = currentStream.DataCollection.length; |
|
5716 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
5717 |
+ |
|
5718 |
+ } |
|
5719 |
+ |
|
5720 |
+ // Post Add Activity |
|
5721 |
+ if (lastPieceCheck[0] == messageIdent && lastPieceCheck[1] == 1) { |
|
5722 |
+ $("#sendFileLoader").remove(); |
|
5723 |
+ $("#contact-" + buddy + "-ChatMessage").val(""); |
|
5724 |
+ } |
|
5725 |
+ $("#contact-" + buddy + "-emoji-menu").hide(); |
|
5726 |
+ |
|
5727 |
+ if(buddyObj.recognition != null){ |
|
5728 |
+ buddyObj.recognition.abort(); |
|
5729 |
+ buddyObj.recognition = null; |
|
5730 |
+ } |
|
5731 |
+ |
|
5732 |
+ RefreshStream(buddyObj); |
|
5733 |
+} |
|
5734 |
+ |
|
5735 |
+function ReceiveMessage(message) { |
|
5736 |
+ |
|
5737 |
+ var callerID = message.remoteIdentity.displayName; |
|
5738 |
+ var did = message.remoteIdentity.uri.user; |
|
5739 |
+ |
|
5740 |
+ console.log("New Incoming Message!", "\""+ callerID +"\" <"+ did +">"); |
|
5741 |
+ |
|
5742 |
+ message.data.direction = "inbound"; |
|
5743 |
+ |
|
5744 |
+ if(did.length > DidLength) { |
|
5745 |
+ // Contacts cannot receive Text Messages, because they cannot reply |
|
5746 |
+ // This may change with FAX, Email, WhatsApp etc |
|
5747 |
+ console.warn("DID length greater then extensions length") |
|
5748 |
+ return; |
|
5749 |
+ } |
|
5750 |
+ |
|
5751 |
+ var CurrentCalls = countSessions("0"); |
|
5752 |
+ |
|
5753 |
+ var buddyObj = FindBuddyByDid(did); |
|
5754 |
+ // Make new contact if it's not there |
|
5755 |
+ if(buddyObj == null) { |
|
5756 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
5757 |
+ if(json == null) json = InitUserBuddies(); |
|
5758 |
+ |
|
5759 |
+ // Add Extension |
|
5760 |
+ var id = uID(); |
|
5761 |
+ var dateNow = utcDateNow(); |
|
5762 |
+ json.DataCollection.push({ |
|
5763 |
+ Type: "extension", |
|
5764 |
+ LastActivity: dateNow, |
|
5765 |
+ ExtensionNumber: did, |
|
5766 |
+ MobileNumber: "", |
|
5767 |
+ ContactNumber1: "", |
|
5768 |
+ ContactNumber2: "", |
|
5769 |
+ uID: id, |
|
5770 |
+ cID: null, |
|
5771 |
+ gID: null, |
|
5772 |
+ DisplayName: callerID, |
|
5773 |
+ Position: "", |
|
5774 |
+ Description: "", |
|
5775 |
+ Email: "", |
|
5776 |
+ MemberCount: 0 |
|
5777 |
+ }); |
|
5778 |
+ buddyObj = new Buddy("extension", id, callerID, did, "", "", "", dateNow, "", ""); |
|
5779 |
+ AddBuddy(buddyObj, true, (CurrentCalls==0), true); |
|
5780 |
+ |
|
5781 |
+ // Update Size |
|
5782 |
+ json.TotalRows = json.DataCollection.length; |
|
5783 |
+ |
|
5784 |
+ // Save To DB |
|
5785 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
5786 |
+ } |
|
5787 |
+ |
|
5788 |
+ var encryptedtext = message.body; |
|
5789 |
+ var originalMessageArr = encryptedtext.split("|"); |
|
5790 |
+ |
|
5791 |
+ if (originalMessageArr[3] != '' && typeof originalMessageArr[3] != 'undefined' && originalMessageArr[3] != null) { |
|
5792 |
+ var fileSentDuringChat = 1; |
|
5793 |
+ var recFileName = originalMessageArr[3]; |
|
5794 |
+ } else { |
|
5795 |
+ var fileSentDuringChat = 0; |
|
5796 |
+ var recFileName = ''; |
|
5797 |
+ } |
|
5798 |
+ |
|
5799 |
+ var currentMId = originalMessageArr[0]; |
|
5800 |
+ var totalPieceNo = parseInt(originalMessageArr[1]); |
|
5801 |
+ var currentPieceNo = parseInt(originalMessageArr[2]); |
|
5802 |
+ |
|
5803 |
+ // Reassemble the original message and decrypt it |
|
5804 |
+ if (currentPieceNo == 0) { |
|
5805 |
+ |
|
5806 |
+ if (splitMessage.hasOwnProperty(currentMId)) { |
|
5807 |
+ |
|
5808 |
+ if (currentPieceNo == 0) { |
|
5809 |
+ var aesPayload = originalMessageArr[4]; |
|
5810 |
+ var newdecrypt = new JSEncrypt(); |
|
5811 |
+ newdecrypt.setPrivateKey(currentChatPrivKey); |
|
5812 |
+ var decAESKeyCon = newdecrypt.decrypt(aesPayload); |
|
5813 |
+ splitMessage[currentMId].aeskeyandiv = decAESKeyCon; |
|
5814 |
+ |
|
5815 |
+ } else { |
|
5816 |
+ splitMessage[currentMId][currentPieceNo] = originalMessageArr[4]; |
|
5817 |
+ } |
|
5818 |
+ |
|
5819 |
+ } else { |
|
5820 |
+ |
|
5821 |
+ if (currentPieceNo == 0) { |
|
5822 |
+ var aesPayload = originalMessageArr[4]; |
|
5823 |
+ var newdecrypt = new JSEncrypt(); |
|
5824 |
+ newdecrypt.setPrivateKey(currentChatPrivKey); |
|
5825 |
+ var decAESKeyCon = newdecrypt.decrypt(aesPayload); |
|
5826 |
+ splitMessage[currentMId] = { "aeskeyandiv": decAESKeyCon }; |
|
5827 |
+ |
|
5828 |
+ } else { |
|
5829 |
+ splitMessage[currentMId] = { [currentPieceNo]: originalMessageArr[4] }; |
|
5830 |
+ } |
|
5831 |
+ |
|
5832 |
+ } |
|
5833 |
+ |
|
5834 |
+ return; |
|
5835 |
+ |
|
5836 |
+ } else if (currentPieceNo < (totalPieceNo - 1)) { |
|
5837 |
+ |
|
5838 |
+ if (splitMessage.hasOwnProperty(currentMId)) { |
|
5839 |
+ splitMessage[currentMId][currentPieceNo] = originalMessageArr[4]; |
|
5840 |
+ } else { |
|
5841 |
+ splitMessage[currentMId] = { [currentPieceNo]: originalMessageArr[4] }; |
|
5842 |
+ } |
|
5843 |
+ |
|
5844 |
+ return; |
|
5845 |
+ |
|
5846 |
+ } else if (currentPieceNo == (totalPieceNo - 1)) { |
|
5847 |
+ |
|
5848 |
+ if (splitMessage.hasOwnProperty(currentMId)) { |
|
5849 |
+ splitMessage[currentMId][currentPieceNo] = originalMessageArr[4]; |
|
5850 |
+ } else { |
|
5851 |
+ splitMessage[currentMId] = { [currentPieceNo]: originalMessageArr[4] }; |
|
5852 |
+ } |
|
5853 |
+ |
|
5854 |
+ if (Object.keys(splitMessage[currentMId]).length == totalPieceNo) { |
|
5855 |
+ |
|
5856 |
+ var decryptAesKey = splitMessage[currentMId]["aeskeyandiv"]; |
|
5857 |
+ |
|
5858 |
+ delete splitMessage[currentMId]["aeskeyandiv"]; |
|
5859 |
+ var origMessageEnc = ''; |
|
5860 |
+ var orderedMPieces = Object.keys(splitMessage[currentMId]).sort().reduce(function(obj, key) { |
|
5861 |
+ obj[key] = splitMessage[currentMId][key]; |
|
5862 |
+ return obj; |
|
5863 |
+ },{}); |
|
5864 |
+ |
|
5865 |
+ Object.keys(orderedMPieces).forEach(function(key, index) { |
|
5866 |
+ origMessageEnc += splitMessage[currentMId][key]; |
|
5867 |
+ }); |
|
5868 |
+ |
|
5869 |
+ var originalMessage = decryptAES(origMessageEnc, decryptAesKey); |
|
5870 |
+ |
|
5871 |
+ delete splitMessage[currentMId]; |
|
5872 |
+ |
|
5873 |
+ } else { return; } |
|
5874 |
+ } |
|
5875 |
+ |
|
5876 |
+ var messageId = uID(); |
|
5877 |
+ var DateTime = utcDateNow(); |
|
5878 |
+ |
|
5879 |
+ // Get the actual person sending (since all group messages come from the group) |
|
5880 |
+ var ActualSender = ""; |
|
5881 |
+ if(buddyObj.type == "group") { |
|
5882 |
+ var assertedIdentity = message.request.headers["P-Asserted-Identity"][0].raw; // Name Surname <ExtNo> |
|
5883 |
+ var bits = assertedIdentity.split(" <"); |
|
5884 |
+ var CallerID = bits[0]; |
|
5885 |
+ var CallerIDNum = bits[1].replace(">", ""); |
|
5886 |
+ |
|
5887 |
+ ActualSender = CallerID; // P-Asserted-Identity; |
|
5888 |
+ } |
|
5889 |
+ |
|
5890 |
+ // Current stream |
|
5891 |
+ var currentStream = JSON.parse(localDB.getItem(buddyObj.identity + "-stream")); |
|
5892 |
+ if(currentStream == null) currentStream = InitinaliseStream(buddyObj.identity); |
|
5893 |
+ |
|
5894 |
+ // Add new message |
|
5895 |
+ var newMessageJson = { |
|
5896 |
+ ItemId: messageId, |
|
5897 |
+ ItemType: "MSG", |
|
5898 |
+ ItemDate: DateTime, |
|
5899 |
+ SrcUserId: buddyObj.identity, |
|
5900 |
+ Src: "\""+ buddyObj.CallerIDName +"\" <"+ buddyObj.ExtNo +">", |
|
5901 |
+ DstUserId: profileUserID, |
|
5902 |
+ Dst: "", |
|
5903 |
+ MessageData: originalMessage |
|
5904 |
+ } |
|
5905 |
+ |
|
5906 |
+ // If a file is received, add the received file section |
|
5907 |
+ if (fileSentDuringChat == 1 && recFileName != '') { |
|
5908 |
+ |
|
5909 |
+ fileSentDuringChat = 0; |
|
5910 |
+ |
|
5911 |
+ var newMessageId = uID(); |
|
5912 |
+ var newDateTime = moment.utc().format("YYYY-MM-DD HH:mm:ss UTC"); |
|
5913 |
+ |
|
5914 |
+ var newFileMessageJson = { |
|
5915 |
+ ItemId: newMessageId, |
|
5916 |
+ ItemType: "FILE", |
|
5917 |
+ ItemDate: newDateTime, |
|
5918 |
+ SrcUserId: buddyObj.identity, |
|
5919 |
+ Src: "\""+ buddyObj.CallerIDName +"\" <"+ buddyObj.ExtNo +">", |
|
5920 |
+ DstUserId: profileUserID, |
|
5921 |
+ Dst: profileUser, |
|
5922 |
+ ReceivedFileName: recFileName, |
|
5923 |
+ MessageData: "Download file" |
|
5924 |
+ } |
|
5925 |
+ |
|
5926 |
+ currentStream.DataCollection.push(newFileMessageJson); |
|
5927 |
+ } |
|
5928 |
+ |
|
5929 |
+ currentStream.DataCollection.push(newMessageJson); |
|
5930 |
+ |
|
5931 |
+ currentStream.TotalRows = currentStream.DataCollection.length; |
|
5932 |
+ localDB.setItem(buddyObj.identity + "-stream", JSON.stringify(currentStream)); |
|
5933 |
+ |
|
5934 |
+ // Update Last Activity |
|
5935 |
+ // ==================== |
|
5936 |
+ UpdateBuddyActivity(buddyObj.identity); |
|
5937 |
+ RefreshStream(buddyObj); |
|
5938 |
+ |
|
5939 |
+ // Handle Stream Not visible |
|
5940 |
+ // ========================= |
|
5941 |
+ var streamVisible = $("#stream-"+ buddyObj.identity).is(":visible"); |
|
5942 |
+ if (!streamVisible) { |
|
5943 |
+ // Add or Increase the Badge |
|
5944 |
+ IncreaseMissedBadge(buddyObj.identity); |
|
5945 |
+ if ("Notification" in window) { |
|
5946 |
+ if (Notification.permission === "granted") { |
|
5947 |
+ var imageUrl = getPicture(buddyObj.identity); |
|
5948 |
+ var noticeOptions = { body: originalMessage.substring(0, 250), icon: imageUrl } |
|
5949 |
+ var inComingChatNotification = new Notification(lang.message_from + " : " + buddyObj.CallerIDName, noticeOptions); |
|
5950 |
+ inComingChatNotification.onclick = function (event) { |
|
5951 |
+ // Show Message |
|
5952 |
+ SelectBuddy(buddyObj.identity); |
|
5953 |
+ } |
|
5954 |
+ } |
|
5955 |
+ } |
|
5956 |
+ // Play Alert |
|
5957 |
+ console.log("Audio:", audioBlobs.Alert.url); |
|
5958 |
+ var rinnger = new Audio(audioBlobs.Alert.blob); |
|
5959 |
+ rinnger.preload = "auto"; |
|
5960 |
+ rinnger.loop = false; |
|
5961 |
+ rinnger.oncanplaythrough = function(e) { |
|
5962 |
+ if (typeof rinnger.sinkId !== 'undefined' && getRingerOutputID() != "default") { |
|
5963 |
+ rinnger.setSinkId(getRingerOutputID()).then(function() { |
|
5964 |
+ console.log("Set sinkId to:", getRingerOutputID()); |
|
5965 |
+ }).catch(function(e){ |
|
5966 |
+ console.warn("Failed not apply setSinkId.", e); |
|
5967 |
+ }); |
|
5968 |
+ } |
|
5969 |
+ // If there has been no interaction with the page at all... this page will not work |
|
5970 |
+ rinnger.play().then(function(){ |
|
5971 |
+ // Audio Is Playing |
|
5972 |
+ }).catch(function(e){ |
|
5973 |
+ console.warn("Unable to play audio file.", e); |
|
5974 |
+ }); |
|
5975 |
+ } |
|
5976 |
+ message.data.rinngerObj = rinnger; // Will be attached to this object until its disposed. |
|
5977 |
+ } else { |
|
5978 |
+ // Message window is active. |
|
5979 |
+ } |
|
5980 |
+} |
|
5981 |
+function AddCallMessage(buddy, session, reasonCode, reasonText) { |
|
5982 |
+ |
|
5983 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
5984 |
+ if(currentStream == null) currentStream = InitinaliseStream(buddy); |
|
5985 |
+ |
|
5986 |
+ var CallEnd = moment.utc(); // Take Now as the Hangup Time |
|
5987 |
+ var callDuration = 0; |
|
5988 |
+ var totalDuration = 0; |
|
5989 |
+ var ringTime = 0; |
|
5990 |
+ |
|
5991 |
+ var CallStart = moment.utc(session.data.callstart.replace(" UTC", "")); // Actual start (both inbound and outbound) |
|
5992 |
+ var CallAnswer = null; // On Accept when inbound, Remote Side when Outbound |
|
5993 |
+ if(session.startTime){ |
|
5994 |
+ // The time when WE answered the call (May be null - no answer) |
|
5995 |
+ // or |
|
5996 |
+ // The time when THEY answered the call (May be null - no answer) |
|
5997 |
+ CallAnswer = moment.utc(session.startTime); // Local Time gets converted to UTC |
|
5998 |
+ |
|
5999 |
+ callDuration = moment.duration(CallEnd.diff(CallAnswer)); |
|
6000 |
+ ringTime = moment.duration(CallAnswer.diff(CallStart)); |
|
6001 |
+ } |
|
6002 |
+ totalDuration = moment.duration(CallEnd.diff(CallStart)); |
|
6003 |
+ |
|
6004 |
+ console.log(session.data.reasonCode + "("+ session.data.reasonText +")") |
|
6005 |
+ |
|
6006 |
+ var srcId = ""; |
|
6007 |
+ var srcCallerID = ""; |
|
6008 |
+ var dstId = "" |
|
6009 |
+ var dstCallerID = ""; |
|
6010 |
+ if(session.data.calldirection == "inbound") { |
|
6011 |
+ srcId = buddy; |
|
6012 |
+ dstId = profileUserID; |
|
6013 |
+ srcCallerID = "<"+ session.remoteIdentity.uri.user +"> "+ session.remoteIdentity.displayName; |
|
6014 |
+ dstCallerID = "<"+ profileUser+"> "+ profileName; |
|
6015 |
+ } else if(session.data.calldirection == "outbound") { |
|
6016 |
+ srcId = profileUserID; |
|
6017 |
+ dstId = buddy; |
|
6018 |
+ srcCallerID = "<"+ profileUser+"> "+ profileName; |
|
6019 |
+ dstCallerID = session.remoteIdentity.uri.user; |
|
6020 |
+ } |
|
6021 |
+ |
|
6022 |
+ var callDirection = session.data.calldirection; |
|
6023 |
+ var withVideo = session.data.withvideo; |
|
6024 |
+ var sessionId = session.id; |
|
6025 |
+ var hanupBy = session.data.terminateby; |
|
6026 |
+ |
|
6027 |
+ var newMessageJson = { |
|
6028 |
+ CdrId: uID(), |
|
6029 |
+ ItemType: "CDR", |
|
6030 |
+ ItemDate: CallStart.format("YYYY-MM-DD HH:mm:ss UTC"), |
|
6031 |
+ CallAnswer: (CallAnswer)? CallAnswer.format("YYYY-MM-DD HH:mm:ss UTC") : null, |
|
6032 |
+ CallEnd: CallEnd.format("YYYY-MM-DD HH:mm:ss UTC"), |
|
6033 |
+ SrcUserId: srcId, |
|
6034 |
+ Src: srcCallerID, |
|
6035 |
+ DstUserId: dstId, |
|
6036 |
+ Dst: dstCallerID, |
|
6037 |
+ RingTime: (ringTime != 0)? ringTime.asSeconds() : 0, |
|
6038 |
+ Billsec: (callDuration != 0)? callDuration.asSeconds() : 0, |
|
6039 |
+ TotalDuration: (totalDuration != 0)? totalDuration.asSeconds() : 0, |
|
6040 |
+ ReasonCode: reasonCode, |
|
6041 |
+ ReasonText: reasonText, |
|
6042 |
+ WithVideo: withVideo, |
|
6043 |
+ SessionId: sessionId, |
|
6044 |
+ CallDirection: callDirection, |
|
6045 |
+ Terminate: hanupBy, |
|
6046 |
+ // CRM |
|
6047 |
+ MessageData: null, |
|
6048 |
+ Tags: [], |
|
6049 |
+ //Reporting |
|
6050 |
+ Transfers: (session.data.transfer)? session.data.transfer : [], |
|
6051 |
+ Mutes: (session.data.mute)? session.data.mute : [], |
|
6052 |
+ Holds: (session.data.hold)? session.data.hold : [], |
|
6053 |
+ Recordings: (session.data.recordings)? session.data.recordings : [], |
|
6054 |
+ ConfCalls: (session.data.confcalls)? session.data.confcalls : [], |
|
6055 |
+ QOS: [] |
|
6056 |
+ } |
|
6057 |
+ |
|
6058 |
+ console.log("New CDR", newMessageJson); |
|
6059 |
+ |
|
6060 |
+ currentStream.DataCollection.push(newMessageJson); |
|
6061 |
+ currentStream.TotalRows = currentStream.DataCollection.length; |
|
6062 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
6063 |
+ |
|
6064 |
+ UpdateBuddyActivity(buddy); |
|
6065 |
+} |
|
6066 |
+ |
|
6067 |
+function SendImageDataMessage(buddy, ImgDataUrl) { |
|
6068 |
+ if (userAgent == null) return; |
|
6069 |
+ if (!userAgent.isRegistered()) return; |
|
6070 |
+ |
|
6071 |
+ // Ajax Upload |
|
6072 |
+ // =========== |
|
6073 |
+ |
|
6074 |
+ var DateTime = moment.utc().format("YYYY-MM-DD HH:mm:ss UTC"); |
|
6075 |
+ var formattedMessage = '<IMG class=previewImage onClick="PreviewImage(this)" src="'+ ImgDataUrl +'">'; |
|
6076 |
+ var messageString = "<table class=\"ourChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr><td style=\"width: 80px\">" |
|
6077 |
+ + "<div class=messageDate>" + DateTime + "</div>" |
|
6078 |
+ + "</td><td>" |
|
6079 |
+ + "<div class=ourChatMessageText>" + formattedMessage + "</div>" |
|
6080 |
+ + "</td></tr></table>"; |
|
6081 |
+ $("#contact-" + buddy + "-ChatHistory").append(messageString); |
|
6082 |
+ updateScroll(buddy); |
|
6083 |
+ |
|
6084 |
+ ImageEditor_Cancel(buddy); |
|
6085 |
+ |
|
6086 |
+ UpdateBuddyActivity(buddy); |
|
6087 |
+} |
|
6088 |
+ |
|
6089 |
+function SendFileDataMessage(buddy, FileDataUrl, fileName, fileSize) { |
|
6090 |
+ if (userAgent == null) return; |
|
6091 |
+ if (!userAgent.isRegistered()) return; |
|
6092 |
+ |
|
6093 |
+ var fileID = uID(); |
|
6094 |
+ |
|
6095 |
+ // Ajax Upload |
|
6096 |
+ // =========== |
|
6097 |
+ $.ajax({ |
|
6098 |
+ type:'POST', |
|
6099 |
+ url: '/api/', |
|
6100 |
+ data: "<XML>"+ FileDataUrl +"</XML>", |
|
6101 |
+ xhr: function(e) { |
|
6102 |
+ var myXhr = $.ajaxSettings.xhr(); |
|
6103 |
+ if(myXhr.upload){ |
|
6104 |
+ myXhr.upload.addEventListener('progress',function(event){ |
|
6105 |
+ var percent = (event.loaded / event.total) * 100; |
|
6106 |
+ console.log("Progress for upload to "+ buddy +" ("+ fileID +"):"+ percent); |
|
6107 |
+ $("#FileProgress-Bar-"+ fileID).css("width", percent +"%"); |
|
6108 |
+ }, false); |
|
6109 |
+ } |
|
6110 |
+ return myXhr; |
|
6111 |
+ }, |
|
6112 |
+ success:function(data, status, jqXHR){ |
|
6113 |
+ // console.log(data); |
|
6114 |
+ $("#FileUpload-"+ fileID).html("Sent"); |
|
6115 |
+ $("#FileProgress-"+ fileID).hide(); |
|
6116 |
+ $("#FileProgress-Bar-"+ fileID).css("width", "0%"); |
|
6117 |
+ }, |
|
6118 |
+ error: function(data, status, error){ |
|
6119 |
+ // console.log(data); |
|
6120 |
+ $("#FileUpload-"+ fileID).html("Failed ("+ data.status +")"); |
|
6121 |
+ $("#FileProgress-"+ fileID).hide(); |
|
6122 |
+ $("#FileProgress-Bar-"+ fileID).css("width", "100%"); |
|
6123 |
+ } |
|
6124 |
+ }); |
|
6125 |
+ |
|
6126 |
+ // Add To Message Stream |
|
6127 |
+ // ===================== |
|
6128 |
+ var DateTime = utcDateNow(); |
|
6129 |
+ |
|
6130 |
+ var showReview = false; |
|
6131 |
+ var fileIcon = '<i class="fa fa-file"></i>'; |
|
6132 |
+ // Image Icons |
|
6133 |
+ if(fileName.toLowerCase().endsWith(".png")) { |
|
6134 |
+ fileIcon = '<i class="fa fa-file-image-o"></i>'; |
|
6135 |
+ showReview = true; |
|
6136 |
+ } |
|
6137 |
+ if(fileName.toLowerCase().endsWith(".jpg")) { |
|
6138 |
+ fileIcon = '<i class="fa fa-file-image-o"></i>'; |
|
6139 |
+ showReview = true; |
|
6140 |
+ } |
|
6141 |
+ if(fileName.toLowerCase().endsWith(".jpeg")) { |
|
6142 |
+ fileIcon = '<i class="fa fa-file-image-o"></i>'; |
|
6143 |
+ showReview = true; |
|
6144 |
+ } |
|
6145 |
+ if(fileName.toLowerCase().endsWith(".bmp")) { |
|
6146 |
+ fileIcon = '<i class="fa fa-file-image-o"></i>'; |
|
6147 |
+ showReview = true; |
|
6148 |
+ } |
|
6149 |
+ if(fileName.toLowerCase().endsWith(".gif")) { |
|
6150 |
+ fileIcon = '<i class="fa fa-file-image-o"></i>'; |
|
6151 |
+ showReview = true; |
|
6152 |
+ } |
|
6153 |
+ // video Icons |
|
6154 |
+ if(fileName.toLowerCase().endsWith(".mov")) fileIcon = '<i class="fa fa-file-video-o"></i>'; |
|
6155 |
+ if(fileName.toLowerCase().endsWith(".avi")) fileIcon = '<i class="fa fa-file-video-o"></i>'; |
|
6156 |
+ if(fileName.toLowerCase().endsWith(".mpeg")) fileIcon = '<i class="fa fa-file-video-o"></i>'; |
|
6157 |
+ if(fileName.toLowerCase().endsWith(".mp4")) fileIcon = '<i class="fa fa-file-video-o"></i>'; |
|
6158 |
+ if(fileName.toLowerCase().endsWith(".mvk")) fileIcon = '<i class="fa fa-file-video-o"></i>'; |
|
6159 |
+ if(fileName.toLowerCase().endsWith(".webm")) fileIcon = '<i class="fa fa-file-video-o"></i>'; |
|
6160 |
+ // Audio Icons |
|
6161 |
+ if(fileName.toLowerCase().endsWith(".wav")) fileIcon = '<i class="fa fa-file-audio-o"></i>'; |
|
6162 |
+ if(fileName.toLowerCase().endsWith(".mp3")) fileIcon = '<i class="fa fa-file-audio-o"></i>'; |
|
6163 |
+ if(fileName.toLowerCase().endsWith(".ogg")) fileIcon = '<i class="fa fa-file-audio-o"></i>'; |
|
6164 |
+ // Compressed Icons |
|
6165 |
+ if(fileName.toLowerCase().endsWith(".zip")) fileIcon = '<i class="fa fa-file-archive-o"></i>'; |
|
6166 |
+ if(fileName.toLowerCase().endsWith(".rar")) fileIcon = '<i class="fa fa-file-archive-o"></i>'; |
|
6167 |
+ if(fileName.toLowerCase().endsWith(".tar.gz")) fileIcon = '<i class="fa fa-file-archive-o"></i>'; |
|
6168 |
+ // Pdf Icons |
|
6169 |
+ if(fileName.toLowerCase().endsWith(".pdf")) fileIcon = '<i class="fa fa-file-pdf-o"></i>'; |
|
6170 |
+ |
|
6171 |
+ var formattedMessage = "<DIV><SPAN id=\"FileUpload-"+ fileID +"\">Sending</SPAN>: "+ fileIcon +" "+ fileName +"</DIV>" |
|
6172 |
+ formattedMessage += "<DIV id=\"FileProgress-"+ fileID +"\" class=\"progressBarContainer\"><DIV id=\"FileProgress-Bar-"+ fileID +"\" class=\"progressBarTrack\"></DIV></DIV>" |
|
6173 |
+ if(showReview){ |
|
6174 |
+ formattedMessage += "<DIV><IMG class=previewImage onClick=\"PreviewImage(this)\" src=\""+ FileDataUrl +"\"></DIV>"; |
|
6175 |
+ } |
|
6176 |
+ |
|
6177 |
+ var messageString = "<table class=\"ourChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr><td style=\"width: 80px\">" |
|
6178 |
+ + "<div class=messageDate>" + DateTime + "</div>" |
|
6179 |
+ + "</td><td>" |
|
6180 |
+ + "<div class=ourChatMessageText>" + formattedMessage + "</div>" |
|
6181 |
+ + "</td></tr></table>"; |
|
6182 |
+ $("#contact-" + buddy + "-ChatHistory").append(messageString); |
|
6183 |
+ updateScroll(buddy); |
|
6184 |
+ |
|
6185 |
+ ImageEditor_Cancel(buddy); |
|
6186 |
+ |
|
6187 |
+ // Update Last Activity |
|
6188 |
+ // ==================== |
|
6189 |
+ UpdateBuddyActivity(buddy); |
|
6190 |
+} |
|
6191 |
+function updateLineScroll(lineNum) { |
|
6192 |
+ RefreshLineActivity(lineNum); |
|
6193 |
+ |
|
6194 |
+ var element = $("#line-"+ lineNum +"-CallDetails").get(0); |
|
6195 |
+ element.scrollTop = element.scrollHeight; |
|
6196 |
+} |
|
6197 |
+function updateScroll(buddy) { |
|
6198 |
+ var history = $("#contact-"+ buddy +"-ChatHistory"); |
|
6199 |
+ if(history.children().length > 0) history.children().last().get(0).scrollIntoView(false); |
|
6200 |
+ history.get(0).scrollTop = history.get(0).scrollHeight; |
|
6201 |
+} |
|
6202 |
+function PreviewImage(obj){ |
|
6203 |
+ |
|
6204 |
+ $.jeegoopopup.close(); |
|
6205 |
+ var previewimgHtml = '<div>'; |
|
6206 |
+ previewimgHtml += '<div class="UiWindowField scroller">'; |
|
6207 |
+ previewimgHtml += '<div><img src="'+ obj.src +'"/></div>'; |
|
6208 |
+ previewimgHtml += '</div></div>'; |
|
6209 |
+ |
|
6210 |
+ $.jeegoopopup.open({ |
|
6211 |
+ title: 'Preview Image', |
|
6212 |
+ html: previewimgHtml, |
|
6213 |
+ width: '800', |
|
6214 |
+ height: '600', |
|
6215 |
+ center: true, |
|
6216 |
+ scrolling: 'no', |
|
6217 |
+ skinClass: 'jg_popup_basic', |
|
6218 |
+ overlay: true, |
|
6219 |
+ opacity: 50, |
|
6220 |
+ draggable: true, |
|
6221 |
+ resizable: false, |
|
6222 |
+ fadeIn: 0 |
|
6223 |
+ }); |
|
6224 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
6225 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
6226 |
+} |
|
6227 |
+ |
|
6228 |
+// Missed Item Notification |
|
6229 |
+// ======================== |
|
6230 |
+function IncreaseMissedBadge(buddy) { |
|
6231 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
6232 |
+ if(buddyObj == null) return; |
|
6233 |
+ |
|
6234 |
+ // Up the Missed Count |
|
6235 |
+ // =================== |
|
6236 |
+ buddyObj.missed += 1; |
|
6237 |
+ |
|
6238 |
+ // Take Out |
|
6239 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
6240 |
+ if(json != null) { |
|
6241 |
+ $.each(json.DataCollection, function (i, item) { |
|
6242 |
+ if(item.uID == buddy || item.cID == buddy || item.gID == buddy){ |
|
6243 |
+ item.missed = item.missed +1; |
|
6244 |
+ return false; |
|
6245 |
+ } |
|
6246 |
+ }); |
|
6247 |
+ // Put Back |
|
6248 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
6249 |
+ } |
|
6250 |
+ |
|
6251 |
+ // Update Badge |
|
6252 |
+ // ============ |
|
6253 |
+ $("#contact-" + buddy + "-missed").text(buddyObj.missed); |
|
6254 |
+ $("#contact-" + buddy + "-missed").show(); |
|
6255 |
+ console.log("Set Missed badge for "+ buddy +" to: "+ buddyObj.missed); |
|
6256 |
+} |
|
6257 |
+function UpdateBuddyActivity(buddy){ |
|
6258 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
6259 |
+ if(buddyObj == null) return; |
|
6260 |
+ |
|
6261 |
+ // Update Last Activity Time |
|
6262 |
+ // ========================= |
|
6263 |
+ var timeStamp = utcDateNow(); |
|
6264 |
+ buddyObj.lastActivity = timeStamp; |
|
6265 |
+ console.log("Last Activity is now: "+ timeStamp); |
|
6266 |
+ |
|
6267 |
+ // Take Out |
|
6268 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
6269 |
+ if(json != null) { |
|
6270 |
+ $.each(json.DataCollection, function (i, item) { |
|
6271 |
+ if(item.uID == buddy || item.cID == buddy || item.gID == buddy){ |
|
6272 |
+ item.LastActivity = timeStamp; |
|
6273 |
+ return false; |
|
6274 |
+ } |
|
6275 |
+ }); |
|
6276 |
+ // Put Back |
|
6277 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
6278 |
+ } |
|
6279 |
+ |
|
6280 |
+ // List Update |
|
6281 |
+ // =========== |
|
6282 |
+ UpdateBuddyList(); |
|
6283 |
+} |
|
6284 |
+function ClearMissedBadge(buddy) { |
|
6285 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
6286 |
+ if(buddyObj == null) return; |
|
6287 |
+ |
|
6288 |
+ buddyObj.missed = 0; |
|
6289 |
+ |
|
6290 |
+ // Take Out |
|
6291 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
6292 |
+ if(json != null) { |
|
6293 |
+ $.each(json.DataCollection, function (i, item) { |
|
6294 |
+ if(item.uID == buddy || item.cID == buddy || item.gID == buddy){ |
|
6295 |
+ item.missed = 0; |
|
6296 |
+ return false; |
|
6297 |
+ } |
|
6298 |
+ }); |
|
6299 |
+ // Put Back |
|
6300 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
6301 |
+ } |
|
6302 |
+ |
|
6303 |
+ $("#contact-" + buddy + "-missed").text(buddyObj.missed); |
|
6304 |
+ $("#contact-" + buddy + "-missed").hide(400); |
|
6305 |
+} |
|
6306 |
+ |
|
6307 |
+// Outbound Calling |
|
6308 |
+// ================ |
|
6309 |
+function VideoCall(lineObj, dialledNumber) { |
|
6310 |
+ if (userAgent == null) return; |
|
6311 |
+ if (!userAgent.isRegistered()) return; |
|
6312 |
+ if(lineObj == null) return; |
|
6313 |
+ |
|
6314 |
+ if(HasAudioDevice == false){ |
|
6315 |
+ Alert(lang.alert_no_microphone); |
|
6316 |
+ return; |
|
6317 |
+ } |
|
6318 |
+ |
|
6319 |
+ if(HasVideoDevice == false){ |
|
6320 |
+ console.warn("No video devices (webcam) found, switching to audio call."); |
|
6321 |
+ AudioCall(lineObj, dialledNumber); |
|
6322 |
+ return; |
|
6323 |
+ } |
|
6324 |
+ |
|
6325 |
+ var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); |
|
6326 |
+ var spdOptions = { |
|
6327 |
+ sessionDescriptionHandlerOptions: { |
|
6328 |
+ constraints: { |
|
6329 |
+ audio: { deviceId : "default" }, |
|
6330 |
+ video: { deviceId : "default" } |
|
6331 |
+ } |
|
6332 |
+ } |
|
6333 |
+ } |
|
6334 |
+ |
|
6335 |
+ // Configure Audio |
|
6336 |
+ var currentAudioDevice = getAudioSrcID(); |
|
6337 |
+ if(currentAudioDevice != "default"){ |
|
6338 |
+ var confirmedAudioDevice = false; |
|
6339 |
+ for (var i = 0; i < AudioinputDevices.length; ++i) { |
|
6340 |
+ if(currentAudioDevice == AudioinputDevices[i].deviceId) { |
|
6341 |
+ confirmedAudioDevice = true; |
|
6342 |
+ break; |
|
6343 |
+ } |
|
6344 |
+ } |
|
6345 |
+ if(confirmedAudioDevice) { |
|
6346 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.deviceId = { exact: currentAudioDevice } |
|
6347 |
+ } |
|
6348 |
+ else { |
|
6349 |
+ console.warn("The audio device you used before is no longer available, default settings applied."); |
|
6350 |
+ localDB.setItem("AudioSrcId", "default"); |
|
6351 |
+ } |
|
6352 |
+ } |
|
6353 |
+ // Add additional Constraints |
|
6354 |
+ if(supportedConstraints.autoGainControl) { |
|
6355 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl = AutoGainControl; |
|
6356 |
+ } |
|
6357 |
+ if(supportedConstraints.echoCancellation) { |
|
6358 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation = EchoCancellation; |
|
6359 |
+ } |
|
6360 |
+ if(supportedConstraints.noiseSuppression) { |
|
6361 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression = NoiseSuppression; |
|
6362 |
+ } |
|
6363 |
+ |
|
6364 |
+ // Configure Video |
|
6365 |
+ var currentVideoDevice = getVideoSrcID(); |
|
6366 |
+ if(currentVideoDevice != "default"){ |
|
6367 |
+ var confirmedVideoDevice = false; |
|
6368 |
+ for (var i = 0; i < VideoinputDevices.length; ++i) { |
|
6369 |
+ if(currentVideoDevice == VideoinputDevices[i].deviceId) { |
|
6370 |
+ confirmedVideoDevice = true; |
|
6371 |
+ break; |
|
6372 |
+ } |
|
6373 |
+ } |
|
6374 |
+ if(confirmedVideoDevice){ |
|
6375 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.deviceId = { exact: currentVideoDevice } |
|
6376 |
+ } |
|
6377 |
+ else { |
|
6378 |
+ console.warn("The video device you used before is no longer available, default settings applied."); |
|
6379 |
+ localDB.setItem("VideoSrcId", "default"); // resets for later and subsequent calls |
|
6380 |
+ } |
|
6381 |
+ } |
|
6382 |
+ // Add additional Constraints |
|
6383 |
+ if(supportedConstraints.frameRate && maxFrameRate != "") { |
|
6384 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.frameRate = maxFrameRate; |
|
6385 |
+ } |
|
6386 |
+ if(supportedConstraints.height && videoHeight != "") { |
|
6387 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.height = videoHeight; |
|
6388 |
+ } |
|
6389 |
+ console.log(supportedConstraints) |
|
6390 |
+ console.log(supportedConstraints.aspectRatio) |
|
6391 |
+ console.log(videoAspectRatio) |
|
6392 |
+ if(supportedConstraints.aspectRatio && videoAspectRatio != "") { |
|
6393 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.aspectRatio = videoAspectRatio; |
|
6394 |
+ } |
|
6395 |
+ |
|
6396 |
+ $("#line-" + lineObj.LineNumber + "-msg").html(lang.starting_video_call); |
|
6397 |
+ $("#line-" + lineObj.LineNumber + "-timer").show(); |
|
6398 |
+ |
|
6399 |
+ // Invite |
|
6400 |
+ console.log("INVITE (video): " + dialledNumber + "@" + wssServer, spdOptions); |
|
6401 |
+ lineObj.SipSession = userAgent.invite("sip:" + dialledNumber + "@" + wssServer, spdOptions); |
|
6402 |
+ |
|
6403 |
+ var startTime = moment.utc(); |
|
6404 |
+ lineObj.SipSession.data.line = lineObj.LineNumber; |
|
6405 |
+ lineObj.SipSession.data.buddyId = lineObj.BuddyObj.identity; |
|
6406 |
+ lineObj.SipSession.data.calldirection = "outbound"; |
|
6407 |
+ lineObj.SipSession.data.dst = dialledNumber; |
|
6408 |
+ lineObj.SipSession.data.callstart = startTime.format("YYYY-MM-DD HH:mm:ss UTC"); |
|
6409 |
+ lineObj.SipSession.data.callTimer = window.setInterval(function(){ |
|
6410 |
+ var now = moment.utc(); |
|
6411 |
+ var duration = moment.duration(now.diff(startTime)); |
|
6412 |
+ $("#line-" + lineObj.LineNumber + "-timer").html(formatShortDuration(duration.asSeconds())); |
|
6413 |
+ }, 1000); |
|
6414 |
+ lineObj.SipSession.data.VideoSourceDevice = getVideoSrcID(); |
|
6415 |
+ lineObj.SipSession.data.AudioSourceDevice = getAudioSrcID(); |
|
6416 |
+ lineObj.SipSession.data.AudioOutputDevice = getAudioOutputID(); |
|
6417 |
+ lineObj.SipSession.data.terminateby = "them"; |
|
6418 |
+ lineObj.SipSession.data.withvideo = true; |
|
6419 |
+ |
|
6420 |
+ updateLineScroll(lineObj.LineNumber); |
|
6421 |
+ |
|
6422 |
+ // Do Necessary UI Wireup |
|
6423 |
+ wireupVideoSession(lineObj); |
|
6424 |
+ |
|
6425 |
+ // Custom Web hook |
|
6426 |
+ if(typeof web_hook_on_invite !== 'undefined') web_hook_on_invite(lineObj.SipSession); |
|
6427 |
+} |
|
6428 |
+ |
|
6429 |
+function ComposeEmail(buddy, obj, event) { |
|
6430 |
+ |
|
6431 |
+ event.stopPropagation(); |
|
6432 |
+ SelectBuddy(buddy); |
|
6433 |
+ |
|
6434 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
6435 |
+ |
|
6436 |
+ $("#roundcubeFrame").remove(); |
|
6437 |
+ $("#rightContent").show(); |
|
6438 |
+ $(".streamSelected").each(function() { $(this).css("display", "none"); }); |
|
6439 |
+ $("#rightContent").append('<iframe id="roundcubeFrame" name="displayFrame"></iframe>'); |
|
6440 |
+ |
|
6441 |
+ var rcDomain = ''; |
|
6442 |
+ var rcBasicAuthUser = ''; |
|
6443 |
+ var rcBasicAuthPass = ''; |
|
6444 |
+ var rcUsername = ''; |
|
6445 |
+ var rcPasswd = ''; |
|
6446 |
+ |
|
6447 |
+ $.ajax({ |
|
6448 |
+ 'async': false, |
|
6449 |
+ 'global': false, |
|
6450 |
+ type: "POST", |
|
6451 |
+ url: "get-email-info.php", |
|
6452 |
+ dataType: "JSON", |
|
6453 |
+ data: { |
|
6454 |
+ username: userName, |
|
6455 |
+ s_ajax_call: validateSToken |
|
6456 |
+ }, |
|
6457 |
+ success: function(datafromdb) { |
|
6458 |
+ rcDomain = datafromdb.rcdomain; |
|
6459 |
+ rcBasicAuthUser = encodeURIComponent(datafromdb.rcbasicauthuser); |
|
6460 |
+ rcBasicAuthPass = encodeURIComponent(datafromdb.rcbasicauthpass); |
|
6461 |
+ rcUsername = datafromdb.rcuser; |
|
6462 |
+ rcPasswd = datafromdb.rcpassword; |
|
6463 |
+ }, |
|
6464 |
+ error: function(datafromdb) { |
|
6465 |
+ alert("An error occurred while trying to retrieve data from the database!"); |
|
6466 |
+ } |
|
6467 |
+ }); |
|
6468 |
+ |
|
6469 |
+ if (rcBasicAuthUser != '' && rcBasicAuthPass != '') { |
|
6470 |
+ var loginURL = "https://"+ rcBasicAuthUser +":"+ rcBasicAuthPass +"@"+ rcDomain +"/"; |
|
6471 |
+ var composeURL = "https://"+ rcBasicAuthUser +":"+ rcBasicAuthPass +"@"+ rcDomain +"/?_task=mail&_action=compose&_to="+ encodeURIComponent(buddyObj.Email) +""; |
|
6472 |
+ } else { |
|
6473 |
+ var loginURL = "https://"+ rcDomain +"/"; |
|
6474 |
+ var composeURL = "https://"+ rcDomain +"/?_task=mail&_action=compose&_to="+ encodeURIComponent(buddyObj.Email) +""; |
|
6475 |
+ } |
|
6476 |
+ |
|
6477 |
+ var form = '<form id="rcForm" method="POST" action="'+ loginURL +'" target="displayFrame">'; |
|
6478 |
+ form += '<input type="hidden" name="_action" value="login" />'; |
|
6479 |
+ form += '<input type="hidden" name="_task" value="login" />'; |
|
6480 |
+ form += '<input type="hidden" name="_autologin" value="1" />'; |
|
6481 |
+ form += '<input name="_user" value="'+ rcUsername +'" type="text" />'; |
|
6482 |
+ form += '<input name="_pass" value="'+ rcPasswd +'" type="password" />'; |
|
6483 |
+ form += '<input id="submitButton" type="submit" value="Login" />'; |
|
6484 |
+ form += '</form>'; |
|
6485 |
+ |
|
6486 |
+ $("#roundcubeFrame").append(form); |
|
6487 |
+ |
|
6488 |
+ if (RCLoginCheck == 0) { |
|
6489 |
+ $("#submitButton").click(); |
|
6490 |
+ RCLoginCheck = 1; |
|
6491 |
+ |
|
6492 |
+ if (rcBasicAuthUser != '' && rcBasicAuthPass != '') { |
|
6493 |
+ if (confirm('You are about to log in to the site "'+ rcDomain +'" with the username "'+ rcBasicAuthUser +'".')) { |
|
6494 |
+ $("#roundcubeFrame").attr("src", composeURL); |
|
6495 |
+ } |
|
6496 |
+ } else { setTimeout(function() { $("#roundcubeFrame").attr("src", composeURL); }, 1000); } |
|
6497 |
+ |
|
6498 |
+ } else { $("#roundcubeFrame").attr("src", composeURL); } |
|
6499 |
+} |
|
6500 |
+function AudioCallMenu(buddy, obj){ |
|
6501 |
+ |
|
6502 |
+ if (($(window).width() - event.pageX) > 54) { var leftPos = event.pageX - 222; } else { var leftPos = event.pageX - 276; } |
|
6503 |
+ if (($(window).height() - event.pageY) > 140) { var topPos = event.pageY + 27; } else { var topPos = event.pageY - 80; } |
|
6504 |
+ |
|
6505 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
6506 |
+ |
|
6507 |
+ if(buddyObj.type == "extension") { |
|
6508 |
+ |
|
6509 |
+ // Extension |
|
6510 |
+ var menu = "<div id=quickCallMenu>"; |
|
6511 |
+ menu += "<table id=quickCallTable cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
6512 |
+ |
|
6513 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-phone-square\"></i></td><td>"+ lang.call_extension + "</td><td><span class=quickNumToDial>" + buddyObj.ExtNo + "</span></td></tr>"; |
|
6514 |
+ |
|
6515 |
+ if (buddyObj.MobileNumber != null && buddyObj.MobileNumber != "") { |
|
6516 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-mobile\"></i></td><td>"+ lang.call_mobile + "</td><td><span class=quickNumToDial>" + buddyObj.MobileNumber + "</span></td></tr>"; |
|
6517 |
+ } |
|
6518 |
+ |
|
6519 |
+ if (buddyObj.ContactNumber1 != null && buddyObj.ContactNumber1 != "") { |
|
6520 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-phone\"></i></td><td>"+ lang.call_number + "</td><td><span class=quickNumToDial>" + buddyObj.ContactNumber1 + "</span></td></tr>"; |
|
6521 |
+ } |
|
6522 |
+ |
|
6523 |
+ if (buddyObj.ContactNumber2 != null && buddyObj.ContactNumber2 != "") { |
|
6524 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-phone\"></i></td><td>"+ lang.call_number + "</td><td><span class=quickNumToDial>" + buddyObj.ContactNumber2 + "</span></td></tr>"; |
|
6525 |
+ } |
|
6526 |
+ |
|
6527 |
+ menu += "</table>"; |
|
6528 |
+ menu += "</div>"; |
|
6529 |
+ |
|
6530 |
+ var consoleLogContent = "Menu click AudioCall("+ buddy +", "; |
|
6531 |
+ |
|
6532 |
+ } else if (buddyObj.type == "contact") { |
|
6533 |
+ |
|
6534 |
+ // Contact |
|
6535 |
+ var menu = "<div id=quickCallMenu>"; |
|
6536 |
+ menu += "<table id=quickCallTable cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
6537 |
+ |
|
6538 |
+ if (buddyObj.MobileNumber != null && buddyObj.MobileNumber != "") { |
|
6539 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-mobile\"></i></td><td>"+ lang.call_mobile + "</td><td><span class=quickNumToDial>" + buddyObj.MobileNumber + "</span></td></tr>"; |
|
6540 |
+ } |
|
6541 |
+ |
|
6542 |
+ if (buddyObj.ContactNumber1 != null && buddyObj.ContactNumber1 != "") { |
|
6543 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-phone\"></i></td><td>"+ lang.call_number + "</td><td><span class=quickNumToDial>" + buddyObj.ContactNumber1 + "</span></td></tr>"; |
|
6544 |
+ } |
|
6545 |
+ |
|
6546 |
+ if (buddyObj.ContactNumber2 != null && buddyObj.ContactNumber2 != "") { |
|
6547 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-phone\"></i></td><td>"+ lang.call_number + "</td><td><span class=quickNumToDial>" + buddyObj.ContactNumber2 + "</span></td></tr>"; |
|
6548 |
+ } |
|
6549 |
+ |
|
6550 |
+ menu += "</table>"; |
|
6551 |
+ menu += "</div>"; |
|
6552 |
+ |
|
6553 |
+ var consoleLogContent = "Menu click AudioCall("+ buddy +", "; |
|
6554 |
+ |
|
6555 |
+ } else if(buddyObj.type == "group") { |
|
6556 |
+ |
|
6557 |
+ var menu = "<div id=quickCallMenu>"; |
|
6558 |
+ menu += "<table id=quickCallTable cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
6559 |
+ menu += "<tr class=quickNumDialRow><td><i class=\"fa fa-users\"></i></td><td>"+ lang.call_group + "</td><td><span class=quickNumToDial>" + buddyObj.ExtNo + "</span></td></tr>"; |
|
6560 |
+ menu += "</table>"; |
|
6561 |
+ menu += "</div>"; |
|
6562 |
+ |
|
6563 |
+ var consoleLogContent = "Menu click AudioCallGroup("+ buddy +", "; |
|
6564 |
+ |
|
6565 |
+ } |
|
6566 |
+ |
|
6567 |
+ $.jeegoopopup.open({ |
|
6568 |
+ html: menu, |
|
6569 |
+ width: 'auto', |
|
6570 |
+ height: 'auto', |
|
6571 |
+ left: leftPos, |
|
6572 |
+ top: topPos, |
|
6573 |
+ scrolling: 'no', |
|
6574 |
+ skinClass: 'jg_popup_basic', |
|
6575 |
+ overlay: true, |
|
6576 |
+ opacity: 0, |
|
6577 |
+ draggable: false, |
|
6578 |
+ resizable: false, |
|
6579 |
+ fadeIn: 0 |
|
6580 |
+ }); |
|
6581 |
+ |
|
6582 |
+ $("#quickCallTable").on("click", ".quickNumDialRow", function() { |
|
6583 |
+ var NumberToDial = $(this).closest("tr").find("span.quickNumToDial").html(); |
|
6584 |
+ console.log(consoleLogContent + NumberToDial +")"); |
|
6585 |
+ DialByLine("audio", buddy, NumberToDial); |
|
6586 |
+ }); |
|
6587 |
+ |
|
6588 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
6589 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
6590 |
+} |
|
6591 |
+function AudioCall(lineObj, dialledNumber) { |
|
6592 |
+ if(userAgent == null) return; |
|
6593 |
+ if(userAgent.isRegistered() == false) return; |
|
6594 |
+ if(lineObj == null) return; |
|
6595 |
+ |
|
6596 |
+ if(HasAudioDevice == false){ |
|
6597 |
+ Alert(lang.alert_no_microphone); |
|
6598 |
+ return; |
|
6599 |
+ } |
|
6600 |
+ |
|
6601 |
+ var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); |
|
6602 |
+ |
|
6603 |
+ var spdOptions = { |
|
6604 |
+ sessionDescriptionHandlerOptions: { |
|
6605 |
+ constraints: { |
|
6606 |
+ audio: { deviceId : "default" }, |
|
6607 |
+ video: false |
|
6608 |
+ } |
|
6609 |
+ } |
|
6610 |
+ } |
|
6611 |
+ // Configure Audio |
|
6612 |
+ var currentAudioDevice = getAudioSrcID(); |
|
6613 |
+ if(currentAudioDevice != "default"){ |
|
6614 |
+ var confirmedAudioDevice = false; |
|
6615 |
+ for (var i = 0; i < AudioinputDevices.length; ++i) { |
|
6616 |
+ if(currentAudioDevice == AudioinputDevices[i].deviceId) { |
|
6617 |
+ confirmedAudioDevice = true; |
|
6618 |
+ break; |
|
6619 |
+ } |
|
6620 |
+ } |
|
6621 |
+ if(confirmedAudioDevice) { |
|
6622 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.deviceId = { exact: currentAudioDevice } |
|
6623 |
+ } |
|
6624 |
+ else { |
|
6625 |
+ console.warn("The audio device you used before is no longer available, default settings applied."); |
|
6626 |
+ localDB.setItem("AudioSrcId", "default"); |
|
6627 |
+ } |
|
6628 |
+ } |
|
6629 |
+ // Add additional Constraints |
|
6630 |
+ if(supportedConstraints.autoGainControl) { |
|
6631 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl = AutoGainControl; |
|
6632 |
+ } |
|
6633 |
+ if(supportedConstraints.echoCancellation) { |
|
6634 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation = EchoCancellation; |
|
6635 |
+ } |
|
6636 |
+ if(supportedConstraints.noiseSuppression) { |
|
6637 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression = NoiseSuppression; |
|
6638 |
+ } |
|
6639 |
+ |
|
6640 |
+ $("#line-" + lineObj.LineNumber + "-msg").html(lang.starting_audio_call); |
|
6641 |
+ $("#line-" + lineObj.LineNumber + "-timer").show(); |
|
6642 |
+ |
|
6643 |
+ // Invite |
|
6644 |
+ console.log("INVITE (audio): " + dialledNumber + "@" + wssServer); |
|
6645 |
+ lineObj.SipSession = userAgent.invite("sip:" + dialledNumber + "@" + wssServer, spdOptions); |
|
6646 |
+ |
|
6647 |
+ var startTime = moment.utc(); |
|
6648 |
+ lineObj.SipSession.data.line = lineObj.LineNumber; |
|
6649 |
+ lineObj.SipSession.data.buddyId = lineObj.BuddyObj.identity; |
|
6650 |
+ lineObj.SipSession.data.calldirection = "outbound"; |
|
6651 |
+ lineObj.SipSession.data.dst = dialledNumber; |
|
6652 |
+ lineObj.SipSession.data.callstart = startTime.format("YYYY-MM-DD HH:mm:ss UTC"); |
|
6653 |
+ lineObj.SipSession.data.callTimer = window.setInterval(function(){ |
|
6654 |
+ var now = moment.utc(); |
|
6655 |
+ var duration = moment.duration(now.diff(startTime)); |
|
6656 |
+ $("#line-" + lineObj.LineNumber + "-timer").html(formatShortDuration(duration.asSeconds())); |
|
6657 |
+ }, 1000); |
|
6658 |
+ lineObj.SipSession.data.VideoSourceDevice = null; |
|
6659 |
+ lineObj.SipSession.data.AudioSourceDevice = getAudioSrcID(); |
|
6660 |
+ lineObj.SipSession.data.AudioOutputDevice = getAudioOutputID(); |
|
6661 |
+ lineObj.SipSession.data.terminateby = "them"; |
|
6662 |
+ lineObj.SipSession.data.withvideo = false; |
|
6663 |
+ |
|
6664 |
+ updateLineScroll(lineObj.LineNumber); |
|
6665 |
+ |
|
6666 |
+ // Do Necessary UI Wireup |
|
6667 |
+ wireupAudioSession(lineObj); |
|
6668 |
+ |
|
6669 |
+ // Custom Web hook |
|
6670 |
+ if(typeof web_hook_on_invite !== 'undefined') web_hook_on_invite(lineObj.SipSession); |
|
6671 |
+} |
|
6672 |
+ |
|
6673 |
+// Sessions & During Call Activity |
|
6674 |
+// =============================== |
|
6675 |
+function getSession(buddy) { |
|
6676 |
+ if(userAgent == null) { |
|
6677 |
+ console.warn("userAgent is null"); |
|
6678 |
+ return; |
|
6679 |
+ } |
|
6680 |
+ if(userAgent.isRegistered() == false) { |
|
6681 |
+ console.warn("userAgent is not registered"); |
|
6682 |
+ return; |
|
6683 |
+ } |
|
6684 |
+ |
|
6685 |
+ var rtnSession = null; |
|
6686 |
+ $.each(userAgent.sessions, function (i, session) { |
|
6687 |
+ if(session.data.buddyId == buddy) { |
|
6688 |
+ rtnSession = session; |
|
6689 |
+ return false; |
|
6690 |
+ } |
|
6691 |
+ }); |
|
6692 |
+ return rtnSession; |
|
6693 |
+} |
|
6694 |
+function countSessions(id){ |
|
6695 |
+ var rtn = 0; |
|
6696 |
+ if(userAgent == null) { |
|
6697 |
+ console.warn("userAgent is null"); |
|
6698 |
+ return 0; |
|
6699 |
+ } |
|
6700 |
+ $.each(userAgent.sessions, function (i, session) { |
|
6701 |
+ if(id != session.id) rtn ++; |
|
6702 |
+ }); |
|
6703 |
+ return rtn; |
|
6704 |
+} |
|
6705 |
+function StartRecording(lineNum){ |
|
6706 |
+ if(CallRecordingPolicy == "disabled") { |
|
6707 |
+ console.warn("Policy Disabled: Call Recording"); |
|
6708 |
+ return; |
|
6709 |
+ } |
|
6710 |
+ var lineObj = FindLineByNumber(lineNum); |
|
6711 |
+ if(lineObj == null) return; |
|
6712 |
+ |
|
6713 |
+ $("#line-"+ lineObj.LineNumber +"-btn-start-recording").hide(); |
|
6714 |
+ $("#line-"+ lineObj.LineNumber +"-btn-stop-recording").show(); |
|
6715 |
+ |
|
6716 |
+ var session = lineObj.SipSession; |
|
6717 |
+ if(session == null){ |
|
6718 |
+ console.warn("Could not find session"); |
|
6719 |
+ return; |
|
6720 |
+ } |
|
6721 |
+ |
|
6722 |
+ var id = uID(); |
|
6723 |
+ |
|
6724 |
+ if(!session.data.recordings) session.data.recordings = []; |
|
6725 |
+ session.data.recordings.push({ |
|
6726 |
+ uID: id, |
|
6727 |
+ startTime: utcDateNow(), |
|
6728 |
+ stopTime: utcDateNow(), |
|
6729 |
+ }); |
|
6730 |
+ |
|
6731 |
+ if(!session.data.mediaRecorder){ |
|
6732 |
+ console.log("Creating call recorder..."); |
|
6733 |
+ var recordStream = new MediaStream(); |
|
6734 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
6735 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
6736 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
6737 |
+ console.log("Adding sender audio track to record:", RTCRtpSender.track.label); |
|
6738 |
+ recordStream.addTrack(RTCRtpSender.track); |
|
6739 |
+ } |
|
6740 |
+ }); |
|
6741 |
+ pc.getReceivers().forEach(function (RTCRtpReceiver) { |
|
6742 |
+ if(RTCRtpReceiver.track && RTCRtpReceiver.track.kind == "audio") { |
|
6743 |
+ console.log("Adding receiver audio track to record:", RTCRtpReceiver.track.label); |
|
6744 |
+ recordStream.addTrack(RTCRtpReceiver.track); |
|
6745 |
+ } |
|
6746 |
+ if(session.data.withvideo){ |
|
6747 |
+ if(RTCRtpReceiver.track && RTCRtpReceiver.track.kind == "video") { |
|
6748 |
+ console.log("Adding receiver video track to record:", RTCRtpReceiver.track.label); |
|
6749 |
+ recordStream.addTrack(RTCRtpReceiver.track); |
|
6750 |
+ } |
|
6751 |
+ } |
|
6752 |
+ }); |
|
6753 |
+ |
|
6754 |
+ // Resample the Video Recording |
|
6755 |
+ if(session.data.withvideo){ |
|
6756 |
+ var recordingWidth = 640; |
|
6757 |
+ var recordingHeight = 360; |
|
6758 |
+ var pnpVideSize = 100; |
|
6759 |
+ if(RecordingVideoSize == "HD"){ |
|
6760 |
+ recordingWidth = 1280; |
|
6761 |
+ recordingHeight = 720; |
|
6762 |
+ pnpVideSize = 144; |
|
6763 |
+ } |
|
6764 |
+ if(RecordingVideoSize == "FHD"){ |
|
6765 |
+ recordingWidth = 1920; |
|
6766 |
+ recordingHeight = 1080; |
|
6767 |
+ pnpVideSize = 240; |
|
6768 |
+ } |
|
6769 |
+ |
|
6770 |
+ // them-pnp |
|
6771 |
+ var pnpVideo = $("#line-" + lineObj.LineNumber + "-localVideo").get(0); |
|
6772 |
+ var mainVideo = $("#line-" + lineObj.LineNumber + "-remoteVideo").get(0); |
|
6773 |
+ if(RecordingLayout == "us-pnp"){ |
|
6774 |
+ pnpVideo = $("#line-" + lineObj.LineNumber + "-remoteVideo").get(0); |
|
6775 |
+ mainVideo = $("#line-" + lineObj.LineNumber + "-localVideo").get(0); |
|
6776 |
+ } |
|
6777 |
+ var recordingCanvas = $('<canvas/>').get(0); |
|
6778 |
+ recordingCanvas.width = (RecordingLayout == "side-by-side")? (recordingWidth * 2) + 5: recordingWidth; |
|
6779 |
+ recordingCanvas.height = recordingHeight; |
|
6780 |
+ var recordingContext = recordingCanvas.getContext("2d"); |
|
6781 |
+ |
|
6782 |
+ window.clearInterval(session.data.recordingRedrawInterval); |
|
6783 |
+ session.data.recordingRedrawInterval = window.setInterval(function(){ |
|
6784 |
+ |
|
6785 |
+ // Main Video |
|
6786 |
+ var videoWidth = (mainVideo.videoWidth > 0)? mainVideo.videoWidth : recordingWidth ; |
|
6787 |
+ var videoHeight = (mainVideo.videoHeight > 0)? mainVideo.videoHeight : recordingHeight ; |
|
6788 |
+ |
|
6789 |
+ if(videoWidth >= videoHeight){ |
|
6790 |
+ // Landscape / Square |
|
6791 |
+ var scale = recordingWidth / videoWidth; |
|
6792 |
+ videoWidth = recordingWidth; |
|
6793 |
+ videoHeight = videoHeight * scale; |
|
6794 |
+ if(videoHeight > recordingHeight){ |
|
6795 |
+ var scale = recordingHeight / videoHeight; |
|
6796 |
+ videoHeight = recordingHeight; |
|
6797 |
+ videoWidth = videoWidth * scale; |
|
6798 |
+ } |
|
6799 |
+ } |
|
6800 |
+ else { |
|
6801 |
+ // Portrait |
|
6802 |
+ var scale = recordingHeight / videoHeight; |
|
6803 |
+ videoHeight = recordingHeight; |
|
6804 |
+ videoWidth = videoWidth * scale; |
|
6805 |
+ } |
|
6806 |
+ var offsetX = (videoWidth < recordingWidth)? (recordingWidth - videoWidth) / 2 : 0; |
|
6807 |
+ var offsetY = (videoHeight < recordingHeight)? (recordingHeight - videoHeight) / 2 : 0; |
|
6808 |
+ if(RecordingLayout == "side-by-side") offsetX = recordingWidth + 5 + offsetX; |
|
6809 |
+ |
|
6810 |
+ // Picture-in-Picture Video |
|
6811 |
+ var pnpVideoHeight = pnpVideo.videoHeight; |
|
6812 |
+ var pnpVideoWidth = pnpVideo.videoWidth; |
|
6813 |
+ if(pnpVideoHeight > 0){ |
|
6814 |
+ if(pnpVideoWidth >= pnpVideoHeight){ |
|
6815 |
+ var scale = pnpVideSize / pnpVideoHeight; |
|
6816 |
+ pnpVideoHeight = pnpVideSize; |
|
6817 |
+ pnpVideoWidth = pnpVideoWidth * scale; |
|
6818 |
+ } |
|
6819 |
+ else{ |
|
6820 |
+ var scale = pnpVideSize / pnpVideoWidth; |
|
6821 |
+ pnpVideoWidth = pnpVideSize; |
|
6822 |
+ pnpVideoHeight = pnpVideoHeight * scale; |
|
6823 |
+ } |
|
6824 |
+ } |
|
6825 |
+ var pnpOffsetX = 10; |
|
6826 |
+ var pnpOffsetY = 10; |
|
6827 |
+ if(RecordingLayout == "side-by-side"){ |
|
6828 |
+ pnpVideoWidth = pnpVideo.videoWidth; |
|
6829 |
+ pnpVideoHeight = pnpVideo.videoHeight; |
|
6830 |
+ if(pnpVideoWidth >= pnpVideoHeight){ |
|
6831 |
+ // Landscape / Square |
|
6832 |
+ var scale = recordingWidth / pnpVideoWidth; |
|
6833 |
+ pnpVideoWidth = recordingWidth; |
|
6834 |
+ pnpVideoHeight = pnpVideoHeight * scale; |
|
6835 |
+ if(pnpVideoHeight > recordingHeight){ |
|
6836 |
+ var scale = recordingHeight / pnpVideoHeight; |
|
6837 |
+ pnpVideoHeight = recordingHeight; |
|
6838 |
+ pnpVideoWidth = pnpVideoWidth * scale; |
|
6839 |
+ } |
|
6840 |
+ } |
|
6841 |
+ else { |
|
6842 |
+ // Portrait |
|
6843 |
+ var scale = recordingHeight / pnpVideoHeight; |
|
6844 |
+ pnpVideoHeight = recordingHeight; |
|
6845 |
+ pnpVideoWidth = pnpVideoWidth * scale; |
|
6846 |
+ } |
|
6847 |
+ pnpOffsetX = (pnpVideoWidth < recordingWidth)? (recordingWidth - pnpVideoWidth) / 2 : 0; |
|
6848 |
+ pnpOffsetY = (pnpVideoHeight < recordingHeight)? (recordingHeight - pnpVideoHeight) / 2 : 0; |
|
6849 |
+ } |
|
6850 |
+ |
|
6851 |
+ // Draw Elements |
|
6852 |
+ recordingContext.fillRect(0, 0, recordingCanvas.width, recordingCanvas.height); |
|
6853 |
+ if(mainVideo.videoHeight > 0){ |
|
6854 |
+ recordingContext.drawImage(mainVideo, offsetX, offsetY, videoWidth, videoHeight); |
|
6855 |
+ } |
|
6856 |
+ if(pnpVideo.videoHeight > 0 && (RecordingLayout == "side-by-side" || RecordingLayout == "us-pnp" || RecordingLayout == "them-pnp")){ |
|
6857 |
+ // Only Draw the Pnp Video when needed |
|
6858 |
+ recordingContext.drawImage(pnpVideo, pnpOffsetX, pnpOffsetY, pnpVideoWidth, pnpVideoHeight); |
|
6859 |
+ } |
|
6860 |
+ }, Math.floor(1000/RecordingVideoFps)); |
|
6861 |
+ var recordingVideoMediaStream = recordingCanvas.captureStream(RecordingVideoFps); |
|
6862 |
+ } |
|
6863 |
+ |
|
6864 |
+ var mixedAudioVideoRecordStream = new MediaStream(); |
|
6865 |
+ mixedAudioVideoRecordStream.addTrack(MixAudioStreams(recordStream).getAudioTracks()[0]); |
|
6866 |
+ if(session.data.withvideo){ |
|
6867 |
+ mixedAudioVideoRecordStream.addTrack(recordingVideoMediaStream.getVideoTracks()[0]); |
|
6868 |
+ } |
|
6869 |
+ |
|
6870 |
+ var mediaType = "audio/webm"; |
|
6871 |
+ if(session.data.withvideo) mediaType = "video/webm"; |
|
6872 |
+ var options = { |
|
6873 |
+ mimeType : mediaType |
|
6874 |
+ } |
|
6875 |
+ var mediaRecorder = new MediaRecorder(mixedAudioVideoRecordStream, options); |
|
6876 |
+ mediaRecorder.data = {} |
|
6877 |
+ mediaRecorder.data.id = ""+ id; |
|
6878 |
+ mediaRecorder.data.sessionId = ""+ session.id; |
|
6879 |
+ mediaRecorder.data.buddyId = ""+ lineObj.BuddyObj.identity; |
|
6880 |
+ mediaRecorder.ondataavailable = function(event) { |
|
6881 |
+ console.log("Got Call Recording Data: ", event.data.size +"Bytes", this.data.id, this.data.buddyId, this.data.sessionId); |
|
6882 |
+ // Save the Audio/Video file |
|
6883 |
+ SaveCallRecording(event.data, this.data.id, this.data.buddyId, this.data.sessionId); |
|
6884 |
+ } |
|
6885 |
+ |
|
6886 |
+ console.log("Starting Call Recording", id); |
|
6887 |
+ session.data.mediaRecorder = mediaRecorder; |
|
6888 |
+ session.data.mediaRecorder.start(); // Safari does not support timeslice |
|
6889 |
+ session.data.recordings[session.data.recordings.length-1].startTime = utcDateNow(); |
|
6890 |
+ |
|
6891 |
+ $("#line-" + lineObj.LineNumber + "-msg").html(lang.call_recording_started); |
|
6892 |
+ |
|
6893 |
+ updateLineScroll(lineNum); |
|
6894 |
+ } |
|
6895 |
+ else if(session.data.mediaRecorder.state == "inactive") { |
|
6896 |
+ session.data.mediaRecorder.data = {} |
|
6897 |
+ session.data.mediaRecorder.data.id = ""+ id; |
|
6898 |
+ session.data.mediaRecorder.data.sessionId = ""+ session.id; |
|
6899 |
+ session.data.mediaRecorder.data.buddyId = ""+ lineObj.BuddyObj.identity; |
|
6900 |
+ |
|
6901 |
+ console.log("Starting Call Recording", id); |
|
6902 |
+ session.data.mediaRecorder.start(); |
|
6903 |
+ session.data.recordings[session.data.recordings.length-1].startTime = utcDateNow(); |
|
6904 |
+ |
|
6905 |
+ $("#line-" + lineObj.LineNumber + "-msg").html(lang.call_recording_started); |
|
6906 |
+ |
|
6907 |
+ updateLineScroll(lineNum); |
|
6908 |
+ } |
|
6909 |
+ else { |
|
6910 |
+ console.warn("Recorder is in an unknown state"); |
|
6911 |
+ } |
|
6912 |
+} |
|
6913 |
+function SaveCallRecording(blob, id, buddy, sessionid){ |
|
6914 |
+ var indexedDB = window.indexedDB; |
|
6915 |
+ var request = indexedDB.open("CallRecordings"); |
|
6916 |
+ request.onerror = function(event) { |
|
6917 |
+ console.error("IndexDB Request Error:", event); |
|
6918 |
+ } |
|
6919 |
+ request.onupgradeneeded = function(event) { |
|
6920 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
6921 |
+ var IDB = event.target.result; |
|
6922 |
+ |
|
6923 |
+ // Create Object Store |
|
6924 |
+ if(IDB.objectStoreNames.contains("Recordings") == false){ |
|
6925 |
+ var objectStore = IDB.createObjectStore("Recordings", { keyPath: "uID" }); |
|
6926 |
+ objectStore.createIndex("sessionid", "sessionid", { unique: false }); |
|
6927 |
+ objectStore.createIndex("bytes", "bytes", { unique: false }); |
|
6928 |
+ objectStore.createIndex("type", "type", { unique: false }); |
|
6929 |
+ objectStore.createIndex("mediaBlob", "mediaBlob", { unique: false }); |
|
6930 |
+ } |
|
6931 |
+ else { |
|
6932 |
+ console.warn("IndexDB requested upgrade, but object store was in place"); |
|
6933 |
+ } |
|
6934 |
+ } |
|
6935 |
+ request.onsuccess = function(event) { |
|
6936 |
+ console.log("IndexDB connected to CallRecordings"); |
|
6937 |
+ |
|
6938 |
+ var IDB = event.target.result; |
|
6939 |
+ if(IDB.objectStoreNames.contains("Recordings") == false){ |
|
6940 |
+ console.warn("IndexDB CallRecordings.Recordings does not exists"); |
|
6941 |
+ return; |
|
6942 |
+ } |
|
6943 |
+ IDB.onerror = function(event) { |
|
6944 |
+ console.error("IndexDB Error:", event); |
|
6945 |
+ } |
|
6946 |
+ |
|
6947 |
+ // Prepare data to write |
|
6948 |
+ var data = { |
|
6949 |
+ uID: id, |
|
6950 |
+ sessionid: sessionid, |
|
6951 |
+ bytes: blob.size, |
|
6952 |
+ type: blob.type, |
|
6953 |
+ mediaBlob: blob |
|
6954 |
+ } |
|
6955 |
+ // Commit Transaction |
|
6956 |
+ var transaction = IDB.transaction(["Recordings"], "readwrite"); |
|
6957 |
+ var objectStoreAdd = transaction.objectStore("Recordings").add(data); |
|
6958 |
+ objectStoreAdd.onsuccess = function(event) { |
|
6959 |
+ console.log("Call Recording Sucess: ", id, blob.size, blob.type, buddy, sessionid); |
|
6960 |
+ } |
|
6961 |
+ } |
|
6962 |
+} |
|
6963 |
+function StopRecording(lineNum, noConfirm){ |
|
6964 |
+ var lineObj = FindLineByNumber(lineNum); |
|
6965 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
6966 |
+ |
|
6967 |
+ var session = lineObj.SipSession; |
|
6968 |
+ if(noConfirm == true){ |
|
6969 |
+ // Called at the end of a call |
|
6970 |
+ $("#line-"+ lineObj.LineNumber +"-btn-start-recording").show(); |
|
6971 |
+ $("#line-"+ lineObj.LineNumber +"-btn-stop-recording").hide(); |
|
6972 |
+ |
|
6973 |
+ if(session.data.mediaRecorder){ |
|
6974 |
+ if(session.data.mediaRecorder.state == "recording"){ |
|
6975 |
+ console.log("Stopping Call Recording"); |
|
6976 |
+ session.data.mediaRecorder.stop(); |
|
6977 |
+ session.data.recordings[session.data.recordings.length-1].stopTime = utcDateNow(); |
|
6978 |
+ window.clearInterval(session.data.recordingRedrawInterval); |
|
6979 |
+ |
|
6980 |
+ $("#line-" + lineObj.LineNumber + "-msg").html(lang.call_recording_stopped); |
|
6981 |
+ |
|
6982 |
+ updateLineScroll(lineNum); |
|
6983 |
+ } |
|
6984 |
+ else{ |
|
6985 |
+ console.warn("Recorder is in an unknow state"); |
|
6986 |
+ } |
|
6987 |
+ } |
|
6988 |
+ return; |
|
6989 |
+ } |
|
6990 |
+ else { |
|
6991 |
+ // User attempts to end call recording |
|
6992 |
+ if(CallRecordingPolicy == "enabled"){ |
|
6993 |
+ console.log("Policy Enabled: Call Recording"); |
|
6994 |
+ } |
|
6995 |
+ |
|
6996 |
+ Confirm(lang.confirm_stop_recording, lang.stop_recording, function(){ |
|
6997 |
+ $("#line-"+ lineObj.LineNumber +"-btn-start-recording").show(); |
|
6998 |
+ $("#line-"+ lineObj.LineNumber +"-btn-stop-recording").hide(); |
|
6999 |
+ |
|
7000 |
+ if(session.data.mediaRecorder){ |
|
7001 |
+ if(session.data.mediaRecorder.state == "recording"){ |
|
7002 |
+ console.log("Stopping Call Recording"); |
|
7003 |
+ session.data.mediaRecorder.stop(); |
|
7004 |
+ session.data.recordings[session.data.recordings.length-1].stopTime = utcDateNow(); |
|
7005 |
+ window.clearInterval(session.data.recordingRedrawInterval); |
|
7006 |
+ |
|
7007 |
+ $("#line-" + lineObj.LineNumber + "-msg").html(lang.call_recording_stopped); |
|
7008 |
+ |
|
7009 |
+ updateLineScroll(lineNum); |
|
7010 |
+ } |
|
7011 |
+ else{ |
|
7012 |
+ console.warn("Recorder is in an unknow state"); |
|
7013 |
+ } |
|
7014 |
+ } |
|
7015 |
+ }); |
|
7016 |
+ } |
|
7017 |
+} |
|
7018 |
+function PlayAudioCallRecording(obj, cdrId, uID){ |
|
7019 |
+ var container = $(obj).parent(); |
|
7020 |
+ container.empty(); |
|
7021 |
+ |
|
7022 |
+ var audioObj = new Audio(); |
|
7023 |
+ audioObj.autoplay = false; |
|
7024 |
+ audioObj.controls = true; |
|
7025 |
+ |
|
7026 |
+ // Make sure you are playing out via the correct device |
|
7027 |
+ var sinkId = getAudioOutputID(); |
|
7028 |
+ if (typeof audioObj.sinkId !== 'undefined') { |
|
7029 |
+ audioObj.setSinkId(sinkId).then(function(){ |
|
7030 |
+ console.log("sinkId applied: "+ sinkId); |
|
7031 |
+ }).catch(function(e){ |
|
7032 |
+ console.warn("Error using setSinkId: ", e); |
|
7033 |
+ }); |
|
7034 |
+ } else { |
|
7035 |
+ console.warn("setSinkId() is not possible using this browser.") |
|
7036 |
+ } |
|
7037 |
+ |
|
7038 |
+ container.append(audioObj); |
|
7039 |
+ |
|
7040 |
+ // Get Call Recording |
|
7041 |
+ var indexedDB = window.indexedDB; |
|
7042 |
+ var request = indexedDB.open("CallRecordings"); |
|
7043 |
+ request.onerror = function(event) { |
|
7044 |
+ console.error("IndexDB Request Error:", event); |
|
7045 |
+ } |
|
7046 |
+ request.onupgradeneeded = function(event) { |
|
7047 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
7048 |
+ } |
|
7049 |
+ request.onsuccess = function(event) { |
|
7050 |
+ console.log("IndexDB connected to CallRecordings"); |
|
7051 |
+ |
|
7052 |
+ var IDB = event.target.result; |
|
7053 |
+ if(IDB.objectStoreNames.contains("Recordings") == false){ |
|
7054 |
+ console.warn("IndexDB CallRecordings.Recordings does not exists"); |
|
7055 |
+ return; |
|
7056 |
+ } |
|
7057 |
+ |
|
7058 |
+ var transaction = IDB.transaction(["Recordings"]); |
|
7059 |
+ var objectStoreGet = transaction.objectStore("Recordings").get(uID); |
|
7060 |
+ objectStoreGet.onerror = function(event) { |
|
7061 |
+ console.error("IndexDB Get Error:", event); |
|
7062 |
+ } |
|
7063 |
+ objectStoreGet.onsuccess = function(event) { |
|
7064 |
+ $("#cdr-media-meta-size-"+ cdrId +"-"+ uID).html(" Size: "+ formatBytes(event.target.result.bytes)); |
|
7065 |
+ $("#cdr-media-meta-codec-"+ cdrId +"-"+ uID).html(" Codec: "+ event.target.result.type); |
|
7066 |
+ |
|
7067 |
+ // Play |
|
7068 |
+ audioObj.src = window.URL.createObjectURL(event.target.result.mediaBlob); |
|
7069 |
+ audioObj.oncanplaythrough = function(){ |
|
7070 |
+ audioObj.play().then(function(){ |
|
7071 |
+ console.log("Playback started"); |
|
7072 |
+ }).catch(function(e){ |
|
7073 |
+ console.error("Error playing back file: ", e); |
|
7074 |
+ }); |
|
7075 |
+ } |
|
7076 |
+ } |
|
7077 |
+ } |
|
7078 |
+} |
|
7079 |
+function PlayVideoCallRecording(obj, cdrId, uID, buddy){ |
|
7080 |
+ var container = $(obj).parent(); |
|
7081 |
+ container.empty(); |
|
7082 |
+ |
|
7083 |
+ var videoObj = $("<video>").get(0); |
|
7084 |
+ videoObj.id = "callrecording-video-"+ cdrId; |
|
7085 |
+ videoObj.autoplay = false; |
|
7086 |
+ videoObj.controls = true; |
|
7087 |
+ videoObj.ontimeupdate = function(event){ |
|
7088 |
+ $("#cdr-video-meta-width-"+ cdrId +"-"+ uID).html(lang.width + " : "+ event.target.videoWidth +"px"); |
|
7089 |
+ $("#cdr-video-meta-height-"+ cdrId +"-"+ uID).html(lang.height +" : "+ event.target.videoHeight +"px"); |
|
7090 |
+ } |
|
7091 |
+ |
|
7092 |
+ var sinkId = getAudioOutputID(); |
|
7093 |
+ if (typeof videoObj.sinkId !== 'undefined') { |
|
7094 |
+ videoObj.setSinkId(sinkId).then(function(){ |
|
7095 |
+ console.log("sinkId applied: "+ sinkId); |
|
7096 |
+ }).catch(function(e){ |
|
7097 |
+ console.warn("Error using setSinkId: ", e); |
|
7098 |
+ }); |
|
7099 |
+ } else { |
|
7100 |
+ console.warn("setSinkId() is not possible using this browser.") |
|
7101 |
+ } |
|
7102 |
+ |
|
7103 |
+ container.append(videoObj); |
|
7104 |
+ |
|
7105 |
+ // Get Call Recording |
|
7106 |
+ var indexedDB = window.indexedDB; |
|
7107 |
+ var request = indexedDB.open("CallRecordings"); |
|
7108 |
+ request.onerror = function(event) { |
|
7109 |
+ console.error("IndexDB Request Error:", event); |
|
7110 |
+ } |
|
7111 |
+ request.onupgradeneeded = function(event) { |
|
7112 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
7113 |
+ } |
|
7114 |
+ request.onsuccess = function(event) { |
|
7115 |
+ console.log("IndexDB connected to CallRecordings"); |
|
7116 |
+ |
|
7117 |
+ var IDB = event.target.result; |
|
7118 |
+ if(IDB.objectStoreNames.contains("Recordings") == false){ |
|
7119 |
+ console.warn("IndexDB CallRecordings.Recordings does not exists"); |
|
7120 |
+ return; |
|
7121 |
+ } |
|
7122 |
+ |
|
7123 |
+ var transaction = IDB.transaction(["Recordings"]); |
|
7124 |
+ var objectStoreGet = transaction.objectStore("Recordings").get(uID); |
|
7125 |
+ objectStoreGet.onerror = function(event) { |
|
7126 |
+ console.error("IndexDB Get Error:", event); |
|
7127 |
+ } |
|
7128 |
+ objectStoreGet.onsuccess = function(event) { |
|
7129 |
+ $("#cdr-media-meta-size-"+ cdrId +"-"+ uID).html(" Size: "+ formatBytes(event.target.result.bytes)); |
|
7130 |
+ $("#cdr-media-meta-codec-"+ cdrId +"-"+ uID).html(" Codec: "+ event.target.result.type); |
|
7131 |
+ |
|
7132 |
+ // Play |
|
7133 |
+ videoObj.src = window.URL.createObjectURL(event.target.result.mediaBlob); |
|
7134 |
+ videoObj.oncanplaythrough = function(){ |
|
7135 |
+ try{ |
|
7136 |
+ videoObj.scrollIntoViewIfNeeded(false); |
|
7137 |
+ } catch(e){} |
|
7138 |
+ videoObj.play().then(function(){ |
|
7139 |
+ console.log("Playback started"); |
|
7140 |
+ }).catch(function(e){ |
|
7141 |
+ console.error("Error playing back file: ", e); |
|
7142 |
+ }); |
|
7143 |
+ |
|
7144 |
+ // Create a Post Image after a second |
|
7145 |
+ if(buddy){ |
|
7146 |
+ window.setTimeout(function(){ |
|
7147 |
+ var canvas = $("<canvas>").get(0); |
|
7148 |
+ var videoWidth = videoObj.videoWidth; |
|
7149 |
+ var videoHeight = videoObj.videoHeight; |
|
7150 |
+ if(videoWidth > videoHeight){ |
|
7151 |
+ // Landscape |
|
7152 |
+ if(videoHeight > 225){ |
|
7153 |
+ var p = 225 / videoHeight; |
|
7154 |
+ videoHeight = 225; |
|
7155 |
+ videoWidth = videoWidth * p; |
|
7156 |
+ } |
|
7157 |
+ } |
|
7158 |
+ else { |
|
7159 |
+ // Portrait |
|
7160 |
+ if(videoHeight > 225){ |
|
7161 |
+ var p = 225 / videoWidth; |
|
7162 |
+ videoWidth = 225; |
|
7163 |
+ videoHeight = videoHeight * p; |
|
7164 |
+ } |
|
7165 |
+ } |
|
7166 |
+ canvas.width = videoWidth; |
|
7167 |
+ canvas.height = videoHeight; |
|
7168 |
+ canvas.getContext('2d').drawImage(videoObj, 0, 0, videoWidth, videoHeight); |
|
7169 |
+ canvas.toBlob(function(blob) { |
|
7170 |
+ var reader = new FileReader(); |
|
7171 |
+ reader.readAsDataURL(blob); |
|
7172 |
+ reader.onloadend = function() { |
|
7173 |
+ var Poster = { width: videoWidth, height: videoHeight, posterBase64: reader.result } |
|
7174 |
+ console.log("Capturing Video Poster..."); |
|
7175 |
+ |
|
7176 |
+ // Update DB |
|
7177 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
7178 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
7179 |
+ $.each(currentStream.DataCollection, function(i, item) { |
|
7180 |
+ if (item.ItemType == "CDR" && item.CdrId == cdrId) { |
|
7181 |
+ // Found |
|
7182 |
+ if(item.Recordings && item.Recordings.length >= 1){ |
|
7183 |
+ $.each(item.Recordings, function(r, recording) { |
|
7184 |
+ if(recording.uID == uID) recording.Poster = Poster; |
|
7185 |
+ }); |
|
7186 |
+ } |
|
7187 |
+ return false; |
|
7188 |
+ } |
|
7189 |
+ }); |
|
7190 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
7191 |
+ console.log("Capturing Video Poster, Done"); |
|
7192 |
+ } |
|
7193 |
+ } |
|
7194 |
+ }, 'image/jpeg', PosterJpegQuality); |
|
7195 |
+ }, 1000); |
|
7196 |
+ } |
|
7197 |
+ } |
|
7198 |
+ } |
|
7199 |
+ } |
|
7200 |
+} |
|
7201 |
+ |
|
7202 |
+// Stream Manipulations |
|
7203 |
+// ==================== |
|
7204 |
+function MixAudioStreams(MultiAudioTackStream){ |
|
7205 |
+ // Takes in a MediaStream with any number of audio tracks and mixes them together |
|
7206 |
+ |
|
7207 |
+ var audioContext = null; |
|
7208 |
+ try { |
|
7209 |
+ window.AudioContext = window.AudioContext || window.webkitAudioContext; |
|
7210 |
+ audioContext = new AudioContext(); |
|
7211 |
+ } |
|
7212 |
+ catch(e){ |
|
7213 |
+ console.warn("AudioContext() not available, cannot record"); |
|
7214 |
+ return MultiAudioTackStream; |
|
7215 |
+ } |
|
7216 |
+ var mixedAudioStream = audioContext.createMediaStreamDestination(); |
|
7217 |
+ MultiAudioTackStream.getAudioTracks().forEach(function(audioTrack){ |
|
7218 |
+ var srcStream = new MediaStream(); |
|
7219 |
+ srcStream.addTrack(audioTrack); |
|
7220 |
+ var streamSourceNode = audioContext.createMediaStreamSource(srcStream); |
|
7221 |
+ streamSourceNode.connect(mixedAudioStream); |
|
7222 |
+ }); |
|
7223 |
+ |
|
7224 |
+ return mixedAudioStream.stream; |
|
7225 |
+} |
|
7226 |
+ |
|
7227 |
+// Call Transfer & Conference |
|
7228 |
+// ============================ |
|
7229 |
+function QuickFindBuddy(obj){ |
|
7230 |
+ |
|
7231 |
+ $.jeegoopopup.close(); |
|
7232 |
+ |
|
7233 |
+ var leftPos = obj.offsetWidth + 178; |
|
7234 |
+ var topPos = obj.offsetHeight + 68; |
|
7235 |
+ |
|
7236 |
+ if($(window).width() < 1467) { |
|
7237 |
+ topPos = obj.offsetHeight + 164; |
|
7238 |
+ if ($(window).width() < 918) { |
|
7239 |
+ leftPos = obj.offsetWidth - 140; |
|
7240 |
+ if($(window).width() < 690) { |
|
7241 |
+ leftPos = obj.offsetWidth - 70; |
|
7242 |
+ topPos = obj.offsetHeight + 164; |
|
7243 |
+ } |
|
7244 |
+ } |
|
7245 |
+ } |
|
7246 |
+ |
|
7247 |
+ var filter = obj.value; |
|
7248 |
+ if(filter == "") return; |
|
7249 |
+ |
|
7250 |
+ console.log("Find Buddy: ", filter); |
|
7251 |
+ |
|
7252 |
+ Buddies.sort(function(a, b){ |
|
7253 |
+ if(a.CallerIDName < b.CallerIDName) return -1; |
|
7254 |
+ if(a.CallerIDName > b.CallerIDName) return 1; |
|
7255 |
+ return 0; |
|
7256 |
+ }); |
|
7257 |
+ |
|
7258 |
+ var visibleItems = 0; |
|
7259 |
+ |
|
7260 |
+ var menu = "<div id=\"quickSearchBuddy\">"; |
|
7261 |
+ menu += "<table id=\"quickSearchBdTable\" cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
7262 |
+ |
|
7263 |
+ for(var b = 0; b < Buddies.length; b++){ |
|
7264 |
+ var buddyObj = Buddies[b]; |
|
7265 |
+ |
|
7266 |
+ // Perform Filter Display |
|
7267 |
+ var display = false; |
|
7268 |
+ if(buddyObj.CallerIDName.toLowerCase().indexOf(filter.toLowerCase()) > -1) display = true; |
|
7269 |
+ if(buddyObj.ExtNo.toLowerCase().indexOf(filter.toLowerCase()) > -1) display = true; |
|
7270 |
+ if(buddyObj.Desc.toLowerCase().indexOf(filter.toLowerCase()) > -1) display = true; |
|
7271 |
+ if(buddyObj.MobileNumber.toLowerCase().indexOf(filter.toLowerCase()) > -1) display = true; |
|
7272 |
+ if(buddyObj.ContactNumber1.toLowerCase().indexOf(filter.toLowerCase()) > -1) display = true; |
|
7273 |
+ if(buddyObj.ContactNumber2.toLowerCase().indexOf(filter.toLowerCase()) > -1) display = true; |
|
7274 |
+ if(display) { |
|
7275 |
+ // Filtered Results |
|
7276 |
+ var iconColor = "#404040"; |
|
7277 |
+ if(buddyObj.presence == "Unknown" || buddyObj.presence == "Not online" || buddyObj.presence == "Unavailable") iconColor = "#666666"; |
|
7278 |
+ if(buddyObj.presence == "Ready") iconColor = "#3fbd3f"; |
|
7279 |
+ if(buddyObj.presence == "On the phone" || buddyObj.presence == "Ringing" || buddyObj.presence == "On hold") iconColor = "#c99606"; |
|
7280 |
+ |
|
7281 |
+ menu += "<tr class=\"quickFindBdTagRow\"><td></td><td><b>"+ buddyObj.CallerIDName +"</b></td><td></td></tr>"; |
|
7282 |
+ |
|
7283 |
+ if (buddyObj.ExtNo != "") { |
|
7284 |
+ menu += "<tr class=\"quickFindBdRow\"><td><i class=\"fa fa-phone-square\" style=\"color:"+ iconColor +"\"></i></td><td>"+ lang.extension +" ("+ buddyObj.presence + ")" +"</td><td><span class=\"quickNumFound\">"+ buddyObj.ExtNo +"</span></td></tr>"; |
|
7285 |
+ } |
|
7286 |
+ if (buddyObj.MobileNumber != "") { |
|
7287 |
+ menu += "<tr class=\"quickFindBdRow\"><td><i class=\"fa fa-mobile\"></i></td><td>"+ lang.mobile +"</td><td><span class=\"quickNumFound\">"+ buddyObj.MobileNumber +"</span></td></tr>"; |
|
7288 |
+ } |
|
7289 |
+ |
|
7290 |
+ if (buddyObj.ContactNumber1 != "") { |
|
7291 |
+ menu += "<tr class=\"quickFindBdRow\"><td><i class=\"fa fa-phone\"></i></td><td>"+ lang.contact_number_1 +"</td><td><span class=\"quickNumFound\">"+ buddyObj.ContactNumber1 +"</span></td></tr>"; |
|
7292 |
+ } |
|
7293 |
+ if (buddyObj.ContactNumber2 != "") { |
|
7294 |
+ menu += "<tr class=\"quickFindBdRow\"><td><i class=\"fa fa-phone\"></i></td><td>"+ lang.contact_number_2 +"</td><td><span class=\"quickNumFound\">"+ buddyObj.ContactNumber2 +"</span></td></tr>"; |
|
7295 |
+ } |
|
7296 |
+ |
|
7297 |
+ visibleItems++; |
|
7298 |
+ } |
|
7299 |
+ if(visibleItems >= 5) break; |
|
7300 |
+ } |
|
7301 |
+ |
|
7302 |
+ menu += "</table></div>"; |
|
7303 |
+ |
|
7304 |
+ if(menu.length > 1) { |
|
7305 |
+ $.jeegoopopup.open({ |
|
7306 |
+ html: menu, |
|
7307 |
+ width: 'auto', |
|
7308 |
+ height: 'auto', |
|
7309 |
+ left: leftPos, |
|
7310 |
+ top: topPos, |
|
7311 |
+ scrolling: 'no', |
|
7312 |
+ skinClass: 'jg_popup_basic', |
|
7313 |
+ overlay: true, |
|
7314 |
+ opacity: 0, |
|
7315 |
+ draggable: false, |
|
7316 |
+ resizable: false, |
|
7317 |
+ fadeIn: 0 |
|
7318 |
+ }); |
|
7319 |
+ |
|
7320 |
+ $("#jg_popup_inner").focus(); |
|
7321 |
+ $("#jg_popup_inner #jg_popup_content #quickSearchBuddy #quickSearchBdTable").on("click", ".quickFindBdRow", function() { |
|
7322 |
+ |
|
7323 |
+ var quickFoundNum = $(this).closest("tr").find("span.quickNumFound").html(); |
|
7324 |
+ |
|
7325 |
+ $.jeegoopopup.close(); |
|
7326 |
+ $(document).find("input[id*='-txt-FindTransferBuddy']").focus(); |
|
7327 |
+ $(document).find("input[id*='-txt-FindTransferBuddy']").val(quickFoundNum); |
|
7328 |
+ }); |
|
7329 |
+ |
|
7330 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
7331 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
7332 |
+ } |
|
7333 |
+} |
|
7334 |
+ |
|
7335 |
+// Call Transfer |
|
7336 |
+// ============= |
|
7337 |
+function StartTransferSession(lineNum){ |
|
7338 |
+ $("#line-"+ lineNum +"-btn-Transfer").hide(); |
|
7339 |
+ $("#line-"+ lineNum +"-btn-CancelTransfer").show(); |
|
7340 |
+ |
|
7341 |
+ holdSession(lineNum); |
|
7342 |
+ $("#line-"+ lineNum +"-txt-FindTransferBuddy").val(""); |
|
7343 |
+ $("#line-"+ lineNum +"-txt-FindTransferBuddy").parent().show(); |
|
7344 |
+ |
|
7345 |
+ $("#line-"+ lineNum +"-btn-blind-transfer").show(); |
|
7346 |
+ $("#line-"+ lineNum +"-btn-attended-transfer").show(); |
|
7347 |
+ $("#line-"+ lineNum +"-btn-complete-transfer").hide(); |
|
7348 |
+ $("#line-"+ lineNum +"-btn-cancel-transfer").hide(); |
|
7349 |
+ |
|
7350 |
+ $("#line-"+ lineNum +"-transfer-status").hide(); |
|
7351 |
+ |
|
7352 |
+ $("#line-"+ lineNum +"-Transfer").show(); |
|
7353 |
+ |
|
7354 |
+ updateLineScroll(lineNum); |
|
7355 |
+} |
|
7356 |
+function CancelTransferSession(lineNum){ |
|
7357 |
+ var lineObj = FindLineByNumber(lineNum); |
|
7358 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
7359 |
+ console.warn("Null line or session"); |
|
7360 |
+ return; |
|
7361 |
+ } |
|
7362 |
+ var session = lineObj.SipSession; |
|
7363 |
+ if(session.data.childsession){ |
|
7364 |
+ console.log("Child Transfer call detected:", session.data.childsession.status) |
|
7365 |
+ try{ |
|
7366 |
+ if(session.data.childsession.status == SIP.Session.C.STATUS_CONFIRMED){ |
|
7367 |
+ session.data.childsession.bye(); |
|
7368 |
+ } |
|
7369 |
+ else{ |
|
7370 |
+ session.data.childsession.cancel(); |
|
7371 |
+ } |
|
7372 |
+ } catch(e){} |
|
7373 |
+ } |
|
7374 |
+ |
|
7375 |
+ $("#line-"+ lineNum +"-btn-Transfer").show(); |
|
7376 |
+ $("#line-"+ lineNum +"-btn-CancelTransfer").hide(); |
|
7377 |
+ |
|
7378 |
+ unholdSession(lineNum); |
|
7379 |
+ $("#line-"+ lineNum +"-Transfer").hide(); |
|
7380 |
+ |
|
7381 |
+ updateLineScroll(lineNum); |
|
7382 |
+} |
|
7383 |
+function BlindTransfer(lineNum) { |
|
7384 |
+ var dstNo = $("#line-"+ lineNum +"-txt-FindTransferBuddy").val().replace(/[^0-9\*\#\+]/g,''); |
|
7385 |
+ if(dstNo == ""){ |
|
7386 |
+ console.warn("Cannot transfer, must be [0-9*+#]"); |
|
7387 |
+ return; |
|
7388 |
+ } |
|
7389 |
+ |
|
7390 |
+ var lineObj = FindLineByNumber(lineNum); |
|
7391 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
7392 |
+ console.warn("Null line or session"); |
|
7393 |
+ return; |
|
7394 |
+ } |
|
7395 |
+ var session = lineObj.SipSession; |
|
7396 |
+ |
|
7397 |
+ if(!session.data.transfer) session.data.transfer = []; |
|
7398 |
+ session.data.transfer.push({ |
|
7399 |
+ type: "Blind", |
|
7400 |
+ to: dstNo, |
|
7401 |
+ transferTime: utcDateNow(), |
|
7402 |
+ disposition: "refer", |
|
7403 |
+ dispositionTime: utcDateNow(), |
|
7404 |
+ accept : { |
|
7405 |
+ complete: null, |
|
7406 |
+ eventTime: null, |
|
7407 |
+ disposition: "" |
|
7408 |
+ } |
|
7409 |
+ }); |
|
7410 |
+ var transferid = session.data.transfer.length-1; |
|
7411 |
+ |
|
7412 |
+ var transferOptions = { |
|
7413 |
+ receiveResponse: function doReceiveResponse(response){ |
|
7414 |
+ console.log("Blind transfer response: ", response.reason_phrase); |
|
7415 |
+ |
|
7416 |
+ session.data.terminateby = "refer"; |
|
7417 |
+ session.data.transfer[transferid].accept.disposition = response.reason_phrase; |
|
7418 |
+ session.data.transfer[transferid].accept.eventTime = utcDateNow(); |
|
7419 |
+ |
|
7420 |
+ $("#line-" + lineNum + "-msg").html("Call Blind Transfered (Accepted)"); |
|
7421 |
+ |
|
7422 |
+ updateLineScroll(lineNum); |
|
7423 |
+ } |
|
7424 |
+ } |
|
7425 |
+ console.log("REFER: ", dstNo + "@" + wssServer); |
|
7426 |
+ session.refer("sip:" + dstNo + "@" + wssServer, transferOptions); |
|
7427 |
+ $("#line-" + lineNum + "-msg").html(lang.call_blind_transfered); |
|
7428 |
+ |
|
7429 |
+ updateLineScroll(lineNum); |
|
7430 |
+} |
|
7431 |
+function AttendedTransfer(lineNum){ |
|
7432 |
+ var dstNo = $("#line-"+ lineNum +"-txt-FindTransferBuddy").val().replace(/[^0-9\*\#\+]/g,''); |
|
7433 |
+ if(dstNo == ""){ |
|
7434 |
+ console.warn("Cannot transfer, must be [0-9*+#]"); |
|
7435 |
+ return; |
|
7436 |
+ } |
|
7437 |
+ |
|
7438 |
+ var lineObj = FindLineByNumber(lineNum); |
|
7439 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
7440 |
+ console.warn("Null line or session"); |
|
7441 |
+ return; |
|
7442 |
+ } |
|
7443 |
+ var session = lineObj.SipSession; |
|
7444 |
+ |
|
7445 |
+ $.jeegoopopup.close(); |
|
7446 |
+ |
|
7447 |
+ $("#line-"+ lineNum +"-txt-FindTransferBuddy").parent().hide(); |
|
7448 |
+ $("#line-"+ lineNum +"-btn-blind-transfer").hide(); |
|
7449 |
+ $("#line-"+ lineNum +"-btn-attended-transfer").hide(); |
|
7450 |
+ |
|
7451 |
+ $("#line-"+ lineNum +"-btn-complete-attended-transfer").hide(); |
|
7452 |
+ $("#line-"+ lineNum +"-btn-cancel-attended-transfer").hide(); |
|
7453 |
+ $("#line-"+ lineNum +"-btn-terminate-attended-transfer").hide(); |
|
7454 |
+ |
|
7455 |
+ var newCallStatus = $("#line-"+ lineNum +"-transfer-status"); |
|
7456 |
+ newCallStatus.html(lang.connecting); |
|
7457 |
+ newCallStatus.show(); |
|
7458 |
+ |
|
7459 |
+ if(!session.data.transfer) session.data.transfer = []; |
|
7460 |
+ session.data.transfer.push({ |
|
7461 |
+ type: "Attended", |
|
7462 |
+ to: dstNo, |
|
7463 |
+ transferTime: utcDateNow(), |
|
7464 |
+ disposition: "invite", |
|
7465 |
+ dispositionTime: utcDateNow(), |
|
7466 |
+ accept : { |
|
7467 |
+ complete: null, |
|
7468 |
+ eventTime: null, |
|
7469 |
+ disposition: "" |
|
7470 |
+ } |
|
7471 |
+ }); |
|
7472 |
+ var transferid = session.data.transfer.length-1; |
|
7473 |
+ |
|
7474 |
+ updateLineScroll(lineNum); |
|
7475 |
+ |
|
7476 |
+ // SDP options |
|
7477 |
+ var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); |
|
7478 |
+ var spdOptions = { |
|
7479 |
+ sessionDescriptionHandlerOptions: { |
|
7480 |
+ constraints: { |
|
7481 |
+ audio: { deviceId : "default" }, |
|
7482 |
+ video: false |
|
7483 |
+ } |
|
7484 |
+ } |
|
7485 |
+ } |
|
7486 |
+ if(session.data.AudioSourceDevice != "default"){ |
|
7487 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.deviceId = { exact: session.data.AudioSourceDevice } |
|
7488 |
+ } |
|
7489 |
+ // Add additional Constraints |
|
7490 |
+ if(supportedConstraints.autoGainControl) { |
|
7491 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl = AutoGainControl; |
|
7492 |
+ } |
|
7493 |
+ if(supportedConstraints.echoCancellation) { |
|
7494 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation = EchoCancellation; |
|
7495 |
+ } |
|
7496 |
+ if(supportedConstraints.noiseSuppression) { |
|
7497 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression = NoiseSuppression; |
|
7498 |
+ } |
|
7499 |
+ |
|
7500 |
+ if(session.data.withvideo){ |
|
7501 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video = true; |
|
7502 |
+ if(session.data.VideoSourceDevice != "default"){ |
|
7503 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.deviceId = { exact: session.data.VideoSourceDevice } |
|
7504 |
+ } |
|
7505 |
+ // Add additional Constraints |
|
7506 |
+ if(supportedConstraints.frameRate && maxFrameRate != "") { |
|
7507 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.frameRate = maxFrameRate; |
|
7508 |
+ } |
|
7509 |
+ if(supportedConstraints.height && videoHeight != "") { |
|
7510 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.height = videoHeight; |
|
7511 |
+ } |
|
7512 |
+ if(supportedConstraints.aspectRatio && videoAspectRatio != "") { |
|
7513 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.aspectRatio = videoAspectRatio; |
|
7514 |
+ } |
|
7515 |
+ } |
|
7516 |
+ |
|
7517 |
+ // Create new call session |
|
7518 |
+ console.log("INVITE: ", "sip:" + dstNo + "@" + wssServer); |
|
7519 |
+ var newSession = userAgent.invite("sip:" + dstNo + "@" + wssServer, spdOptions); |
|
7520 |
+ session.data.childsession = newSession; |
|
7521 |
+ newSession.on('progress', function (response) { |
|
7522 |
+ newCallStatus.html(lang.ringing); |
|
7523 |
+ session.data.transfer[transferid].disposition = "progress"; |
|
7524 |
+ session.data.transfer[transferid].dispositionTime = utcDateNow(); |
|
7525 |
+ |
|
7526 |
+ $("#line-" + lineNum + "-msg").html(lang.attended_transfer_call_started); |
|
7527 |
+ |
|
7528 |
+ var CancelAttendedTransferBtn = $("#line-"+ lineNum +"-btn-cancel-attended-transfer"); |
|
7529 |
+ CancelAttendedTransferBtn.off('click'); |
|
7530 |
+ CancelAttendedTransferBtn.on('click', function(){ |
|
7531 |
+ newSession.cancel(); |
|
7532 |
+ newCallStatus.html(lang.call_cancelled); |
|
7533 |
+ console.log("New call session canceled"); |
|
7534 |
+ |
|
7535 |
+ session.data.transfer[transferid].accept.complete = false; |
|
7536 |
+ session.data.transfer[transferid].accept.disposition = "cancel"; |
|
7537 |
+ session.data.transfer[transferid].accept.eventTime = utcDateNow(); |
|
7538 |
+ |
|
7539 |
+ $("#line-" + lineNum + "-msg").html(lang.attended_transfer_call_cancelled); |
|
7540 |
+ |
|
7541 |
+ updateLineScroll(lineNum); |
|
7542 |
+ }); |
|
7543 |
+ CancelAttendedTransferBtn.show(); |
|
7544 |
+ |
|
7545 |
+ updateLineScroll(lineNum); |
|
7546 |
+ }); |
|
7547 |
+ newSession.on('accepted', function (response) { |
|
7548 |
+ newCallStatus.html(lang.call_in_progress); |
|
7549 |
+ $("#line-"+ lineNum +"-btn-cancel-attended-transfer").hide(); |
|
7550 |
+ session.data.transfer[transferid].disposition = "accepted"; |
|
7551 |
+ session.data.transfer[transferid].dispositionTime = utcDateNow(); |
|
7552 |
+ |
|
7553 |
+ var CompleteTransferBtn = $("#line-"+ lineNum +"-btn-complete-attended-transfer"); |
|
7554 |
+ CompleteTransferBtn.off('click'); |
|
7555 |
+ CompleteTransferBtn.on('click', function(){ |
|
7556 |
+ var transferOptions = { |
|
7557 |
+ receiveResponse: function doReceiveResponse(response){ |
|
7558 |
+ console.log("Attended transfer response: ", response.reason_phrase); |
|
7559 |
+ |
|
7560 |
+ session.data.terminateby = "refer"; |
|
7561 |
+ session.data.transfer[transferid].accept.disposition = response.reason_phrase; |
|
7562 |
+ session.data.transfer[transferid].accept.eventTime = utcDateNow(); |
|
7563 |
+ |
|
7564 |
+ $("#line-" + lineNum + "-msg").html(lang.attended_transfer_complete_accepted); |
|
7565 |
+ |
|
7566 |
+ updateLineScroll(lineNum); |
|
7567 |
+ } |
|
7568 |
+ } |
|
7569 |
+ |
|
7570 |
+ // Send REFER |
|
7571 |
+ session.refer(newSession, transferOptions); |
|
7572 |
+ |
|
7573 |
+ newCallStatus.html(lang.attended_transfer_complete); |
|
7574 |
+ console.log("Attended transfer complete"); |
|
7575 |
+ // Call will now teardown... |
|
7576 |
+ |
|
7577 |
+ session.data.transfer[transferid].accept.complete = true; |
|
7578 |
+ session.data.transfer[transferid].accept.disposition = "refer"; |
|
7579 |
+ session.data.transfer[transferid].accept.eventTime = utcDateNow(); |
|
7580 |
+ |
|
7581 |
+ $("#line-" + lineNum + "-msg").html(lang.attended_transfer_complete); |
|
7582 |
+ |
|
7583 |
+ updateLineScroll(lineNum); |
|
7584 |
+ }); |
|
7585 |
+ CompleteTransferBtn.show(); |
|
7586 |
+ |
|
7587 |
+ updateLineScroll(lineNum); |
|
7588 |
+ |
|
7589 |
+ var TerminateAttendedTransferBtn = $("#line-"+ lineNum +"-btn-terminate-attended-transfer"); |
|
7590 |
+ TerminateAttendedTransferBtn.off('click'); |
|
7591 |
+ TerminateAttendedTransferBtn.on('click', function(){ |
|
7592 |
+ newSession.bye(); |
|
7593 |
+ newCallStatus.html(lang.call_ended); |
|
7594 |
+ console.log("New call session end"); |
|
7595 |
+ |
|
7596 |
+ session.data.transfer[transferid].accept.complete = false; |
|
7597 |
+ session.data.transfer[transferid].accept.disposition = "bye"; |
|
7598 |
+ session.data.transfer[transferid].accept.eventTime = utcDateNow(); |
|
7599 |
+ |
|
7600 |
+ $("#line-" + lineNum + "-msg").html(lang.attended_transfer_call_ended); |
|
7601 |
+ |
|
7602 |
+ updateLineScroll(lineNum); |
|
7603 |
+ }); |
|
7604 |
+ TerminateAttendedTransferBtn.show(); |
|
7605 |
+ |
|
7606 |
+ updateLineScroll(lineNum); |
|
7607 |
+ }); |
|
7608 |
+ newSession.on('trackAdded', function () { |
|
7609 |
+ var pc = newSession.sessionDescriptionHandler.peerConnection; |
|
7610 |
+ |
|
7611 |
+ // Gets Remote Audio Track (Local audio is setup via initial GUM) |
|
7612 |
+ var remoteStream = new MediaStream(); |
|
7613 |
+ pc.getReceivers().forEach(function (receiver) { |
|
7614 |
+ if(receiver.track && receiver.track.kind == "audio"){ |
|
7615 |
+ remoteStream.addTrack(receiver.track); |
|
7616 |
+ } |
|
7617 |
+ }); |
|
7618 |
+ var remoteAudio = $("#line-" + lineNum + "-transfer-remoteAudio").get(0); |
|
7619 |
+ remoteAudio.srcObject = remoteStream; |
|
7620 |
+ remoteAudio.onloadedmetadata = function(e) { |
|
7621 |
+ if (typeof remoteAudio.sinkId !== 'undefined') { |
|
7622 |
+ remoteAudio.setSinkId(session.data.AudioOutputDevice).then(function(){ |
|
7623 |
+ console.log("sinkId applied: "+ session.data.AudioOutputDevice); |
|
7624 |
+ }).catch(function(e){ |
|
7625 |
+ console.warn("Error using setSinkId: ", e); |
|
7626 |
+ }); |
|
7627 |
+ } |
|
7628 |
+ remoteAudio.play(); |
|
7629 |
+ } |
|
7630 |
+ }); |
|
7631 |
+ newSession.on('rejected', function (response, cause) { |
|
7632 |
+ console.log("New call session rejected: ", cause); |
|
7633 |
+ newCallStatus.html(lang.call_rejected); |
|
7634 |
+ session.data.transfer[transferid].disposition = "rejected"; |
|
7635 |
+ session.data.transfer[transferid].dispositionTime = utcDateNow(); |
|
7636 |
+ |
|
7637 |
+ $("#line-"+ lineNum +"-txt-FindTransferBuddy").parent().show(); |
|
7638 |
+ $("#line-"+ lineNum +"-btn-blind-transfer").show(); |
|
7639 |
+ $("#line-"+ lineNum +"-btn-attended-transfer").show(); |
|
7640 |
+ |
|
7641 |
+ $("#line-"+ lineNum +"-btn-complete-attended-transfer").hide(); |
|
7642 |
+ $("#line-"+ lineNum +"-btn-cancel-attended-transfer").hide(); |
|
7643 |
+ $("#line-"+ lineNum +"-btn-terminate-attended-transfer").hide(); |
|
7644 |
+ |
|
7645 |
+ $("#line-"+ lineNum +"-msg").html(lang.attended_transfer_call_rejected); |
|
7646 |
+ |
|
7647 |
+ updateLineScroll(lineNum); |
|
7648 |
+ |
|
7649 |
+ window.setTimeout(function(){ |
|
7650 |
+ newCallStatus.hide(); |
|
7651 |
+ updateLineScroll(lineNum); |
|
7652 |
+ }, 1000); |
|
7653 |
+ }); |
|
7654 |
+ newSession.on('terminated', function (response, cause) { |
|
7655 |
+ console.log("New call session terminated: ", cause); |
|
7656 |
+ newCallStatus.html(lang.call_ended); |
|
7657 |
+ session.data.transfer[transferid].disposition = "terminated"; |
|
7658 |
+ session.data.transfer[transferid].dispositionTime = utcDateNow(); |
|
7659 |
+ |
|
7660 |
+ $("#line-"+ lineNum +"-txt-FindTransferBuddy").parent().show(); |
|
7661 |
+ $("#line-"+ lineNum +"-btn-blind-transfer").show(); |
|
7662 |
+ $("#line-"+ lineNum +"-btn-attended-transfer").show(); |
|
7663 |
+ |
|
7664 |
+ $("#line-"+ lineNum +"-btn-complete-attended-transfer").hide(); |
|
7665 |
+ $("#line-"+ lineNum +"-btn-cancel-attended-transfer").hide(); |
|
7666 |
+ $("#line-"+ lineNum +"-btn-terminate-attended-transfer").hide(); |
|
7667 |
+ |
|
7668 |
+ $("#line-"+ lineNum +"-msg").html(lang.attended_transfer_call_terminated); |
|
7669 |
+ |
|
7670 |
+ updateLineScroll(lineNum); |
|
7671 |
+ |
|
7672 |
+ window.setTimeout(function(){ |
|
7673 |
+ newCallStatus.hide(); |
|
7674 |
+ updateLineScroll(lineNum); |
|
7675 |
+ }, 1000); |
|
7676 |
+ }); |
|
7677 |
+} |
|
7678 |
+ |
|
7679 |
+// Conference Calls |
|
7680 |
+// ================ |
|
7681 |
+function StartConferenceCall(lineNum){ |
|
7682 |
+ $("#line-"+ lineNum +"-btn-Conference").hide(); |
|
7683 |
+ $("#line-"+ lineNum +"-btn-CancelConference").show(); |
|
7684 |
+ |
|
7685 |
+ holdSession(lineNum); |
|
7686 |
+ $("#line-"+ lineNum +"-txt-FindConferenceBuddy").val(""); |
|
7687 |
+ $("#line-"+ lineNum +"-txt-FindConferenceBuddy").parent().show(); |
|
7688 |
+ |
|
7689 |
+ $("#line-"+ lineNum +"-btn-conference-dial").show(); |
|
7690 |
+ $("#line-"+ lineNum +"-btn-cancel-conference-dial").hide(); |
|
7691 |
+ $("#line-"+ lineNum +"-btn-join-conference-call").hide(); |
|
7692 |
+ $("#line-"+ lineNum +"-btn-terminate-conference-call").hide(); |
|
7693 |
+ |
|
7694 |
+ $("#line-"+ lineNum +"-conference-status").hide(); |
|
7695 |
+ |
|
7696 |
+ $("#line-"+ lineNum +"-Conference").show(); |
|
7697 |
+ |
|
7698 |
+ updateLineScroll(lineNum); |
|
7699 |
+} |
|
7700 |
+function CancelConference(lineNum){ |
|
7701 |
+ var lineObj = FindLineByNumber(lineNum); |
|
7702 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
7703 |
+ console.warn("Null line or session"); |
|
7704 |
+ return; |
|
7705 |
+ } |
|
7706 |
+ var session = lineObj.SipSession; |
|
7707 |
+ if(session.data.childsession){ |
|
7708 |
+ try{ |
|
7709 |
+ if(session.data.childsession.status == SIP.Session.C.STATUS_CONFIRMED){ |
|
7710 |
+ session.data.childsession.bye(); |
|
7711 |
+ } |
|
7712 |
+ else{ |
|
7713 |
+ session.data.childsession.cancel(); |
|
7714 |
+ } |
|
7715 |
+ } catch(e){} |
|
7716 |
+ } |
|
7717 |
+ |
|
7718 |
+ $("#line-"+ lineNum +"-btn-Conference").show(); |
|
7719 |
+ $("#line-"+ lineNum +"-btn-CancelConference").hide(); |
|
7720 |
+ |
|
7721 |
+ unholdSession(lineNum); |
|
7722 |
+ $("#line-"+ lineNum +"-Conference").hide(); |
|
7723 |
+ |
|
7724 |
+ updateLineScroll(lineNum); |
|
7725 |
+} |
|
7726 |
+function ConferenceDial(lineNum){ |
|
7727 |
+ var dstNo = $("#line-"+ lineNum +"-txt-FindConferenceBuddy").val().replace(/[^0-9\*\#\+]/g,''); |
|
7728 |
+ if(dstNo == ""){ |
|
7729 |
+ console.warn("Cannot transfer, must be [0-9*+#]"); |
|
7730 |
+ return; |
|
7731 |
+ } |
|
7732 |
+ |
|
7733 |
+ var lineObj = FindLineByNumber(lineNum); |
|
7734 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
7735 |
+ console.warn("Null line or session"); |
|
7736 |
+ return; |
|
7737 |
+ } |
|
7738 |
+ var session = lineObj.SipSession; |
|
7739 |
+ |
|
7740 |
+ $.jeegoopopup.close(); |
|
7741 |
+ |
|
7742 |
+ $("#line-"+ lineNum +"-txt-FindConferenceBuddy").parent().hide(); |
|
7743 |
+ |
|
7744 |
+ $("#line-"+ lineNum +"-btn-conference-dial").hide(); |
|
7745 |
+ $("#line-"+ lineNum +"-btn-cancel-conference-dial") |
|
7746 |
+ $("#line-"+ lineNum +"-btn-join-conference-call").hide(); |
|
7747 |
+ $("#line-"+ lineNum +"-btn-terminate-conference-call").hide(); |
|
7748 |
+ |
|
7749 |
+ var newCallStatus = $("#line-"+ lineNum +"-conference-status"); |
|
7750 |
+ newCallStatus.html(lang.connecting); |
|
7751 |
+ newCallStatus.show(); |
|
7752 |
+ |
|
7753 |
+ if(!session.data.confcalls) session.data.confcalls = []; |
|
7754 |
+ session.data.confcalls.push({ |
|
7755 |
+ to: dstNo, |
|
7756 |
+ startTime: utcDateNow(), |
|
7757 |
+ disposition: "invite", |
|
7758 |
+ dispositionTime: utcDateNow(), |
|
7759 |
+ accept : { |
|
7760 |
+ complete: null, |
|
7761 |
+ eventTime: null, |
|
7762 |
+ disposition: "" |
|
7763 |
+ } |
|
7764 |
+ }); |
|
7765 |
+ var confcallid = session.data.confcalls.length-1; |
|
7766 |
+ |
|
7767 |
+ updateLineScroll(lineNum); |
|
7768 |
+ |
|
7769 |
+ // SDP options |
|
7770 |
+ var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); |
|
7771 |
+ var spdOptions = { |
|
7772 |
+ sessionDescriptionHandlerOptions: { |
|
7773 |
+ constraints: { |
|
7774 |
+ audio: { deviceId : "default" }, |
|
7775 |
+ video: false |
|
7776 |
+ } |
|
7777 |
+ } |
|
7778 |
+ } |
|
7779 |
+ if(session.data.AudioSourceDevice != "default"){ |
|
7780 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.deviceId = { exact: session.data.AudioSourceDevice } |
|
7781 |
+ } |
|
7782 |
+ // Add additional Constraints |
|
7783 |
+ if(supportedConstraints.autoGainControl) { |
|
7784 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl = AutoGainControl; |
|
7785 |
+ } |
|
7786 |
+ if(supportedConstraints.echoCancellation) { |
|
7787 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation = EchoCancellation; |
|
7788 |
+ } |
|
7789 |
+ if(supportedConstraints.noiseSuppression) { |
|
7790 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression = NoiseSuppression; |
|
7791 |
+ } |
|
7792 |
+ |
|
7793 |
+ // Unlikely this will work |
|
7794 |
+ if(session.data.withvideo){ |
|
7795 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video = true; |
|
7796 |
+ if(session.data.VideoSourceDevice != "default"){ |
|
7797 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.deviceId = { exact: session.data.VideoSourceDevice } |
|
7798 |
+ } |
|
7799 |
+ // Add additional Constraints |
|
7800 |
+ if(supportedConstraints.frameRate && maxFrameRate != "") { |
|
7801 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.frameRate = maxFrameRate; |
|
7802 |
+ } |
|
7803 |
+ if(supportedConstraints.height && videoHeight != "") { |
|
7804 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.height = videoHeight; |
|
7805 |
+ } |
|
7806 |
+ if(supportedConstraints.aspectRatio && videoAspectRatio != "") { |
|
7807 |
+ spdOptions.sessionDescriptionHandlerOptions.constraints.video.aspectRatio = videoAspectRatio; |
|
7808 |
+ } |
|
7809 |
+ } |
|
7810 |
+ |
|
7811 |
+ // Create new call session |
|
7812 |
+ console.log("INVITE: ", "sip:" + dstNo + "@" + wssServer); |
|
7813 |
+ var newSession = userAgent.invite("sip:" + dstNo + "@" + wssServer, spdOptions); |
|
7814 |
+ session.data.childsession = newSession; |
|
7815 |
+ newSession.on('progress', function (response) { |
|
7816 |
+ newCallStatus.html(lang.ringing); |
|
7817 |
+ session.data.confcalls[confcallid].disposition = "progress"; |
|
7818 |
+ session.data.confcalls[confcallid].dispositionTime = utcDateNow(); |
|
7819 |
+ |
|
7820 |
+ $("#line-" + lineNum + "-msg").html(lang.conference_call_started); |
|
7821 |
+ |
|
7822 |
+ var CancelConferenceDialBtn = $("#line-"+ lineNum +"-btn-cancel-conference-dial"); |
|
7823 |
+ CancelConferenceDialBtn.off('click'); |
|
7824 |
+ CancelConferenceDialBtn.on('click', function(){ |
|
7825 |
+ newSession.cancel(); |
|
7826 |
+ newCallStatus.html(lang.call_cancelled); |
|
7827 |
+ console.log("New call session canceled"); |
|
7828 |
+ |
|
7829 |
+ session.data.confcalls[confcallid].accept.complete = false; |
|
7830 |
+ session.data.confcalls[confcallid].accept.disposition = "cancel"; |
|
7831 |
+ session.data.confcalls[confcallid].accept.eventTime = utcDateNow(); |
|
7832 |
+ |
|
7833 |
+ $("#line-" + lineNum + "-msg").html(lang.canference_call_cancelled); |
|
7834 |
+ |
|
7835 |
+ updateLineScroll(lineNum); |
|
7836 |
+ }); |
|
7837 |
+ CancelConferenceDialBtn.show(); |
|
7838 |
+ |
|
7839 |
+ updateLineScroll(lineNum); |
|
7840 |
+ }); |
|
7841 |
+ newSession.on('accepted', function (response) { |
|
7842 |
+ newCallStatus.html(lang.call_in_progress); |
|
7843 |
+ $("#line-"+ lineNum +"-btn-cancel-conference-dial").hide(); |
|
7844 |
+ session.data.confcalls[confcallid].complete = true; |
|
7845 |
+ session.data.confcalls[confcallid].disposition = "accepted"; |
|
7846 |
+ session.data.confcalls[confcallid].dispositionTime = utcDateNow(); |
|
7847 |
+ |
|
7848 |
+ // Join Call |
|
7849 |
+ var JoinCallBtn = $("#line-"+ lineNum +"-btn-join-conference-call"); |
|
7850 |
+ JoinCallBtn.off('click'); |
|
7851 |
+ JoinCallBtn.on('click', function(){ |
|
7852 |
+ // Merge Call Audio |
|
7853 |
+ if(!session.data.childsession){ |
|
7854 |
+ console.warn("Conference session lost"); |
|
7855 |
+ return; |
|
7856 |
+ } |
|
7857 |
+ |
|
7858 |
+ var outputStreamForSession = new MediaStream(); |
|
7859 |
+ var outputStreamForConfSession = new MediaStream(); |
|
7860 |
+ |
|
7861 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
7862 |
+ var confPc = session.data.childsession.sessionDescriptionHandler.peerConnection; |
|
7863 |
+ |
|
7864 |
+ // Get conf call input channel |
|
7865 |
+ confPc.getReceivers().forEach(function (RTCRtpReceiver) { |
|
7866 |
+ if(RTCRtpReceiver.track && RTCRtpReceiver.track.kind == "audio") { |
|
7867 |
+ console.log("Adding conference session:", RTCRtpReceiver.track.label); |
|
7868 |
+ outputStreamForSession.addTrack(RTCRtpReceiver.track); |
|
7869 |
+ } |
|
7870 |
+ }); |
|
7871 |
+ |
|
7872 |
+ // Get session input channel |
|
7873 |
+ pc.getReceivers().forEach(function (RTCRtpReceiver) { |
|
7874 |
+ if(RTCRtpReceiver.track && RTCRtpReceiver.track.kind == "audio") { |
|
7875 |
+ console.log("Adding conference session:", RTCRtpReceiver.track.label); |
|
7876 |
+ outputStreamForConfSession.addTrack(RTCRtpReceiver.track); |
|
7877 |
+ } |
|
7878 |
+ }); |
|
7879 |
+ |
|
7880 |
+ // Replace tracks of Parent Call |
|
7881 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
7882 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
7883 |
+ console.log("Switching to mixed Audio track on session"); |
|
7884 |
+ |
|
7885 |
+ session.data.AudioSourceTrack = RTCRtpSender.track; |
|
7886 |
+ outputStreamForSession.addTrack(RTCRtpSender.track); |
|
7887 |
+ var mixedAudioTrack = MixAudioStreams(outputStreamForSession).getAudioTracks()[0]; |
|
7888 |
+ mixedAudioTrack.IsMixedTrack = true; |
|
7889 |
+ |
|
7890 |
+ RTCRtpSender.replaceTrack(mixedAudioTrack); |
|
7891 |
+ } |
|
7892 |
+ }); |
|
7893 |
+ // Replace tracks of Child Call |
|
7894 |
+ confPc.getSenders().forEach(function (RTCRtpSender) { |
|
7895 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
7896 |
+ console.log("Switching to mixed Audio track on conf call"); |
|
7897 |
+ |
|
7898 |
+ session.data.childsession.data.AudioSourceTrack = RTCRtpSender.track; |
|
7899 |
+ outputStreamForConfSession.addTrack(RTCRtpSender.track); |
|
7900 |
+ var mixedAudioTrackForConf = MixAudioStreams(outputStreamForConfSession).getAudioTracks()[0]; |
|
7901 |
+ mixedAudioTrackForConf.IsMixedTrack = true; |
|
7902 |
+ |
|
7903 |
+ RTCRtpSender.replaceTrack(mixedAudioTrackForConf); |
|
7904 |
+ } |
|
7905 |
+ }); |
|
7906 |
+ |
|
7907 |
+ newCallStatus.html(lang.call_in_progress); |
|
7908 |
+ console.log("Conference Call In Progress"); |
|
7909 |
+ |
|
7910 |
+ session.data.confcalls[confcallid].accept.complete = true; |
|
7911 |
+ session.data.confcalls[confcallid].accept.disposition = "join"; |
|
7912 |
+ session.data.confcalls[confcallid].accept.eventTime = utcDateNow(); |
|
7913 |
+ |
|
7914 |
+ $("#line-"+ lineNum +"-btn-terminate-conference-call").show(); |
|
7915 |
+ |
|
7916 |
+ $("#line-" + lineNum + "-msg").html(lang.conference_call_in_progress); |
|
7917 |
+ |
|
7918 |
+ // Take the parent call off hold |
|
7919 |
+ unholdSession(lineNum); |
|
7920 |
+ |
|
7921 |
+ JoinCallBtn.hide(); |
|
7922 |
+ |
|
7923 |
+ updateLineScroll(lineNum); |
|
7924 |
+ }); |
|
7925 |
+ JoinCallBtn.show(); |
|
7926 |
+ |
|
7927 |
+ updateLineScroll(lineNum); |
|
7928 |
+ |
|
7929 |
+ // End Call |
|
7930 |
+ var TerminateAttendedTransferBtn = $("#line-"+ lineNum +"-btn-terminate-conference-call"); |
|
7931 |
+ TerminateAttendedTransferBtn.off('click'); |
|
7932 |
+ TerminateAttendedTransferBtn.on('click', function(){ |
|
7933 |
+ newSession.bye(); |
|
7934 |
+ newCallStatus.html(lang.call_ended); |
|
7935 |
+ console.log("New call session end"); |
|
7936 |
+ |
|
7937 |
+ session.data.confcalls[confcallid].accept.disposition = "bye"; |
|
7938 |
+ session.data.confcalls[confcallid].accept.eventTime = utcDateNow(); |
|
7939 |
+ |
|
7940 |
+ $("#line-" + lineNum + "-msg").html(lang.conference_call_ended); |
|
7941 |
+ |
|
7942 |
+ updateLineScroll(lineNum); |
|
7943 |
+ }); |
|
7944 |
+ TerminateAttendedTransferBtn.show(); |
|
7945 |
+ |
|
7946 |
+ updateLineScroll(lineNum); |
|
7947 |
+ }); |
|
7948 |
+ newSession.on('trackAdded', function () { |
|
7949 |
+ |
|
7950 |
+ var pc = newSession.sessionDescriptionHandler.peerConnection; |
|
7951 |
+ |
|
7952 |
+ // Gets Remote Audio Track (Local audio is setup via initial GUM) |
|
7953 |
+ var remoteStream = new MediaStream(); |
|
7954 |
+ pc.getReceivers().forEach(function (receiver) { |
|
7955 |
+ if(receiver.track && receiver.track.kind == "audio"){ |
|
7956 |
+ remoteStream.addTrack(receiver.track); |
|
7957 |
+ } |
|
7958 |
+ }); |
|
7959 |
+ var remoteAudio = $("#line-" + lineNum + "-conference-remoteAudio").get(0); |
|
7960 |
+ remoteAudio.srcObject = remoteStream; |
|
7961 |
+ remoteAudio.onloadedmetadata = function(e) { |
|
7962 |
+ if (typeof remoteAudio.sinkId !== 'undefined') { |
|
7963 |
+ remoteAudio.setSinkId(session.data.AudioOutputDevice).then(function(){ |
|
7964 |
+ console.log("sinkId applied: "+ session.data.AudioOutputDevice); |
|
7965 |
+ }).catch(function(e){ |
|
7966 |
+ console.warn("Error using setSinkId: ", e); |
|
7967 |
+ }); |
|
7968 |
+ } |
|
7969 |
+ remoteAudio.play(); |
|
7970 |
+ } |
|
7971 |
+ }); |
|
7972 |
+ newSession.on('rejected', function (response, cause) { |
|
7973 |
+ console.log("New call session rejected: ", cause); |
|
7974 |
+ newCallStatus.html(lang.call_rejected); |
|
7975 |
+ session.data.confcalls[confcallid].disposition = "rejected"; |
|
7976 |
+ session.data.confcalls[confcallid].dispositionTime = utcDateNow(); |
|
7977 |
+ |
|
7978 |
+ $("#line-"+ lineNum +"-txt-FindConferenceBuddy").parent().show(); |
|
7979 |
+ $("#line-"+ lineNum +"-btn-conference-dial").show(); |
|
7980 |
+ |
|
7981 |
+ $("#line-"+ lineNum +"-btn-cancel-conference-dial").hide(); |
|
7982 |
+ $("#line-"+ lineNum +"-btn-join-conference-call").hide(); |
|
7983 |
+ $("#line-"+ lineNum +"-btn-terminate-conference-call").hide(); |
|
7984 |
+ |
|
7985 |
+ $("#line-"+ lineNum +"-msg").html(lang.conference_call_rejected); |
|
7986 |
+ |
|
7987 |
+ updateLineScroll(lineNum); |
|
7988 |
+ |
|
7989 |
+ window.setTimeout(function(){ |
|
7990 |
+ newCallStatus.hide(); |
|
7991 |
+ updateLineScroll(lineNum); |
|
7992 |
+ }, 1000); |
|
7993 |
+ }); |
|
7994 |
+ newSession.on('terminated', function (response, cause) { |
|
7995 |
+ console.log("New call session terminated: ", cause); |
|
7996 |
+ newCallStatus.html(lang.call_ended); |
|
7997 |
+ session.data.confcalls[confcallid].disposition = "terminated"; |
|
7998 |
+ session.data.confcalls[confcallid].dispositionTime = utcDateNow(); |
|
7999 |
+ |
|
8000 |
+ // Ends the mixed audio, and releases the mic |
|
8001 |
+ if(session.data.childsession.data.AudioSourceTrack && session.data.childsession.data.AudioSourceTrack.kind == "audio"){ |
|
8002 |
+ session.data.childsession.data.AudioSourceTrack.stop(); |
|
8003 |
+ } |
|
8004 |
+ // Restore Audio Stream if it was changed |
|
8005 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
8006 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
8007 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8008 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
8009 |
+ RTCRtpSender.replaceTrack(session.data.AudioSourceTrack).then(function(){ |
|
8010 |
+ if(session.data.ismute){ |
|
8011 |
+ RTCRtpSender.track.enabled = false; |
|
8012 |
+ } |
|
8013 |
+ }).catch(function(){ |
|
8014 |
+ console.error(e); |
|
8015 |
+ }); |
|
8016 |
+ session.data.AudioSourceTrack = null; |
|
8017 |
+ } |
|
8018 |
+ }); |
|
8019 |
+ } |
|
8020 |
+ $("#line-"+ lineNum +"-txt-FindConferenceBuddy").parent().show(); |
|
8021 |
+ $("#line-"+ lineNum +"-btn-conference-dial").show(); |
|
8022 |
+ |
|
8023 |
+ $("#line-"+ lineNum +"-btn-cancel-conference-dial").hide(); |
|
8024 |
+ $("#line-"+ lineNum +"-btn-join-conference-call").hide(); |
|
8025 |
+ $("#line-"+ lineNum +"-btn-terminate-conference-call").hide(); |
|
8026 |
+ |
|
8027 |
+ $("#line-"+ lineNum +"-msg").html(lang.conference_call_terminated); |
|
8028 |
+ |
|
8029 |
+ updateLineScroll(lineNum); |
|
8030 |
+ |
|
8031 |
+ window.setTimeout(function(){ |
|
8032 |
+ newCallStatus.hide(); |
|
8033 |
+ updateLineScroll(lineNum); |
|
8034 |
+ }, 1000); |
|
8035 |
+ }); |
|
8036 |
+} |
|
8037 |
+ |
|
8038 |
+ |
|
8039 |
+function cancelSession(lineNum) { |
|
8040 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8041 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
8042 |
+ |
|
8043 |
+ lineObj.SipSession.data.terminateby = "us"; |
|
8044 |
+ |
|
8045 |
+ console.log("Cancelling session : "+ lineNum); |
|
8046 |
+ lineObj.SipSession.cancel(); |
|
8047 |
+ |
|
8048 |
+ $("#line-" + lineNum + "-msg").html(lang.call_cancelled); |
|
8049 |
+} |
|
8050 |
+function holdSession(lineNum) { |
|
8051 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8052 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
8053 |
+ |
|
8054 |
+ console.log("Putting Call on hold: "+ lineNum); |
|
8055 |
+ if(lineObj.SipSession.local_hold == false){ |
|
8056 |
+ lineObj.SipSession.hold(); |
|
8057 |
+ } |
|
8058 |
+ // Log Hold |
|
8059 |
+ if(!lineObj.SipSession.data.hold) lineObj.SipSession.data.hold = []; |
|
8060 |
+ lineObj.SipSession.data.hold.push({ event: "hold", eventTime: utcDateNow() }); |
|
8061 |
+ |
|
8062 |
+ $("#line-" + lineNum + "-btn-Hold").hide(); |
|
8063 |
+ $("#line-" + lineNum + "-btn-Unhold").show(); |
|
8064 |
+ $("#line-" + lineNum + "-msg").html(lang.call_on_hold); |
|
8065 |
+ |
|
8066 |
+ updateLineScroll(lineNum); |
|
8067 |
+} |
|
8068 |
+function unholdSession(lineNum) { |
|
8069 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8070 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
8071 |
+ |
|
8072 |
+ console.log("Taking call off hold: "+ lineNum); |
|
8073 |
+ if(lineObj.SipSession.local_hold == true){ |
|
8074 |
+ lineObj.SipSession.unhold(); |
|
8075 |
+ } |
|
8076 |
+ // Log Hold |
|
8077 |
+ if(!lineObj.SipSession.data.hold) lineObj.SipSession.data.hold = []; |
|
8078 |
+ lineObj.SipSession.data.hold.push({ event: "unhold", eventTime: utcDateNow() }); |
|
8079 |
+ |
|
8080 |
+ $("#line-" + lineNum + "-msg").html(lang.call_in_progress); |
|
8081 |
+ $("#line-" + lineNum + "-btn-Hold").show(); |
|
8082 |
+ $("#line-" + lineNum + "-btn-Unhold").hide(); |
|
8083 |
+ |
|
8084 |
+ updateLineScroll(lineNum); |
|
8085 |
+} |
|
8086 |
+function endSession(lineNum) { |
|
8087 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8088 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
8089 |
+ |
|
8090 |
+ console.log("Ending call with: "+ lineNum); |
|
8091 |
+ lineObj.SipSession.data.terminateby = "us"; |
|
8092 |
+ lineObj.SipSession.bye(); |
|
8093 |
+ |
|
8094 |
+ $("#line-" + lineNum + "-msg").html(lang.call_ended); |
|
8095 |
+ $("#line-" + lineNum + "-ActiveCall").hide(); |
|
8096 |
+ |
|
8097 |
+ updateLineScroll(lineNum); |
|
8098 |
+} |
|
8099 |
+function sendDTMF(lineNum, itemStr) { |
|
8100 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8101 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
8102 |
+ |
|
8103 |
+ console.log("Sending DTMF ("+ itemStr +"): "+ lineNum); |
|
8104 |
+ lineObj.SipSession.dtmf(itemStr); |
|
8105 |
+ |
|
8106 |
+ $("#line-" + lineNum + "-msg").html(lang.send_dtmf + ": "+ itemStr); |
|
8107 |
+ |
|
8108 |
+ updateLineScroll(lineNum); |
|
8109 |
+ |
|
8110 |
+ // Custom Web hook |
|
8111 |
+ if(typeof web_hook_on_dtmf !== 'undefined') web_hook_on_dtmf(itemStr, lineObj.SipSession); |
|
8112 |
+} |
|
8113 |
+function switchVideoSource(lineNum, srcId){ |
|
8114 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8115 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
8116 |
+ console.warn("Line or Session is Null"); |
|
8117 |
+ return; |
|
8118 |
+ } |
|
8119 |
+ var session = lineObj.SipSession; |
|
8120 |
+ |
|
8121 |
+ $("#line-" + lineNum + "-msg").html(lang.switching_video_source); |
|
8122 |
+ |
|
8123 |
+ var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); |
|
8124 |
+ var constraints = { |
|
8125 |
+ audio: false, |
|
8126 |
+ video: { deviceId: "default" } |
|
8127 |
+ } |
|
8128 |
+ if(srcId != "default"){ |
|
8129 |
+ constraints.video.deviceId = { exact: srcId } |
|
8130 |
+ } |
|
8131 |
+ |
|
8132 |
+ // Add additional Constraints |
|
8133 |
+ if(supportedConstraints.frameRate && maxFrameRate != "") { |
|
8134 |
+ constraints.video.frameRate = maxFrameRate; |
|
8135 |
+ } |
|
8136 |
+ if(supportedConstraints.height && videoHeight != "") { |
|
8137 |
+ constraints.video.height = videoHeight; |
|
8138 |
+ } |
|
8139 |
+ if(supportedConstraints.aspectRatio && videoAspectRatio != "") { |
|
8140 |
+ constraints.video.aspectRatio = videoAspectRatio; |
|
8141 |
+ } |
|
8142 |
+ |
|
8143 |
+ session.data.VideoSourceDevice = srcId; |
|
8144 |
+ |
|
8145 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
8146 |
+ |
|
8147 |
+ var localStream = new MediaStream(); |
|
8148 |
+ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ |
|
8149 |
+ var newMediaTrack = newStream.getVideoTracks()[0]; |
|
8150 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8151 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "video") { |
|
8152 |
+ console.log("Switching Video Track : "+ RTCRtpSender.track.label + " to "+ newMediaTrack.label); |
|
8153 |
+ RTCRtpSender.track.stop(); |
|
8154 |
+ RTCRtpSender.replaceTrack(newMediaTrack); |
|
8155 |
+ localStream.addTrack(newMediaTrack); |
|
8156 |
+ } |
|
8157 |
+ }); |
|
8158 |
+ }).catch(function(e){ |
|
8159 |
+ console.error("Error on getUserMedia", e, constraints); |
|
8160 |
+ }); |
|
8161 |
+ |
|
8162 |
+ // Restore Audio Stream is it was changed |
|
8163 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
8164 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8165 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
8166 |
+ RTCRtpSender.replaceTrack(session.data.AudioSourceTrack).then(function(){ |
|
8167 |
+ if(session.data.ismute){ |
|
8168 |
+ RTCRtpSender.track.enabled = false; |
|
8169 |
+ } |
|
8170 |
+ }).catch(function(){ |
|
8171 |
+ console.error(e); |
|
8172 |
+ }); |
|
8173 |
+ session.data.AudioSourceTrack = null; |
|
8174 |
+ } |
|
8175 |
+ }); |
|
8176 |
+ } |
|
8177 |
+ |
|
8178 |
+ // Set Preview |
|
8179 |
+ console.log("Showing as preview..."); |
|
8180 |
+ var localVideo = $("#line-" + lineNum + "-localVideo").get(0); |
|
8181 |
+ localVideo.srcObject = localStream; |
|
8182 |
+ localVideo.onloadedmetadata = function(e) { |
|
8183 |
+ localVideo.play(); |
|
8184 |
+ } |
|
8185 |
+} |
|
8186 |
+function SendCanvas(lineNum){ |
|
8187 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8188 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
8189 |
+ console.warn("Line or Session is Null"); |
|
8190 |
+ return; |
|
8191 |
+ } |
|
8192 |
+ var session = lineObj.SipSession; |
|
8193 |
+ |
|
8194 |
+ $("#line-" + lineNum + "-msg").html(lang.switching_to_canvas); |
|
8195 |
+ |
|
8196 |
+ // Create scratch Pad |
|
8197 |
+ RemoveScratchpad(lineNum); |
|
8198 |
+ |
|
8199 |
+ var newCanvas = $('<canvas/>'); |
|
8200 |
+ newCanvas.prop("id", "line-" + lineNum + "-scratchpad"); |
|
8201 |
+ $("#line-" + lineNum + "-scratchpad-container").append(newCanvas); |
|
8202 |
+ $("#line-" + lineNum + "-scratchpad").css("display", "inline-block"); |
|
8203 |
+ $("#line-" + lineNum + "-scratchpad").css("width", "640px"); // SD |
|
8204 |
+ $("#line-" + lineNum + "-scratchpad").css("height", "360px"); // SD |
|
8205 |
+ $("#line-" + lineNum + "-scratchpad").prop("width", 640); // SD |
|
8206 |
+ $("#line-" + lineNum + "-scratchpad").prop("height", 360); // SD |
|
8207 |
+ $("#line-" + lineNum + "-scratchpad-container").show(); |
|
8208 |
+ |
|
8209 |
+ console.log("Canvas for Scratchpad created..."); |
|
8210 |
+ |
|
8211 |
+ scratchpad = new fabric.Canvas("line-" + lineNum + "-scratchpad"); |
|
8212 |
+ scratchpad.id = "line-" + lineNum + "-scratchpad"; |
|
8213 |
+ scratchpad.backgroundColor = "#FFFFFF"; |
|
8214 |
+ scratchpad.isDrawingMode = true; |
|
8215 |
+ scratchpad.renderAll(); |
|
8216 |
+ scratchpad.redrawIntrtval = window.setInterval(function(){ |
|
8217 |
+ scratchpad.renderAll(); |
|
8218 |
+ }, 1000); |
|
8219 |
+ |
|
8220 |
+ CanvasCollection.push(scratchpad); |
|
8221 |
+ |
|
8222 |
+ // Get The Canvas Stream |
|
8223 |
+ var canvasMediaStream = $("#line-"+ lineNum +"-scratchpad").get(0).captureStream(25); |
|
8224 |
+ var canvasMediaTrack = canvasMediaStream.getVideoTracks()[0]; |
|
8225 |
+ |
|
8226 |
+ // Switch Tracks |
|
8227 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
8228 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8229 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "video") { |
|
8230 |
+ console.log("Switching Track : "+ RTCRtpSender.track.label + " to Scratchpad Canvas"); |
|
8231 |
+ RTCRtpSender.track.stop(); |
|
8232 |
+ RTCRtpSender.replaceTrack(canvasMediaTrack); |
|
8233 |
+ } |
|
8234 |
+ }); |
|
8235 |
+ |
|
8236 |
+ // Restore Audio Stream if it was changed |
|
8237 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
8238 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8239 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
8240 |
+ RTCRtpSender.replaceTrack(session.data.AudioSourceTrack).then(function(){ |
|
8241 |
+ if(session.data.ismute){ |
|
8242 |
+ RTCRtpSender.track.enabled = false; |
|
8243 |
+ } |
|
8244 |
+ }).catch(function(){ |
|
8245 |
+ console.error(e); |
|
8246 |
+ }); |
|
8247 |
+ session.data.AudioSourceTrack = null; |
|
8248 |
+ } |
|
8249 |
+ }); |
|
8250 |
+ } |
|
8251 |
+ |
|
8252 |
+ // Set Preview |
|
8253 |
+ // =========== |
|
8254 |
+ console.log("Showing as preview..."); |
|
8255 |
+ var localVideo = $("#line-" + lineNum + "-localVideo").get(0); |
|
8256 |
+ localVideo.srcObject = canvasMediaStream; |
|
8257 |
+ localVideo.onloadedmetadata = function(e) { |
|
8258 |
+ localVideo.play(); |
|
8259 |
+ } |
|
8260 |
+} |
|
8261 |
+function SendVideo(lineNum, src){ |
|
8262 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8263 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
8264 |
+ console.warn("Line or Session is Null"); |
|
8265 |
+ return; |
|
8266 |
+ } |
|
8267 |
+ var session = lineObj.SipSession; |
|
8268 |
+ |
|
8269 |
+ $("#line-"+ lineNum +"-src-camera").prop("disabled", false); |
|
8270 |
+ $("#line-"+ lineNum +"-src-canvas").prop("disabled", false); |
|
8271 |
+ $("#line-"+ lineNum +"-src-desktop").prop("disabled", false); |
|
8272 |
+ $("#line-"+ lineNum +"-src-video").prop("disabled", true); |
|
8273 |
+ $("#line-"+ lineNum +"-src-blank").prop("disabled", false); |
|
8274 |
+ |
|
8275 |
+ $("#line-" + lineNum + "-msg").html(lang.switching_to_shared_video); |
|
8276 |
+ |
|
8277 |
+ $("#line-" + lineNum + "-scratchpad-container").hide(); |
|
8278 |
+ RemoveScratchpad(lineNum); |
|
8279 |
+ $("#line-"+ lineNum +"-sharevideo").hide(); |
|
8280 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).pause(); |
|
8281 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).removeAttribute('src'); |
|
8282 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).load(); |
|
8283 |
+ |
|
8284 |
+ $("#line-"+ lineNum +"-localVideo").hide(); |
|
8285 |
+ $("#line-"+ lineNum +"-remoteVideo").appendTo("#line-" + lineNum + "-preview-container"); |
|
8286 |
+ |
|
8287 |
+ // Create Video Object |
|
8288 |
+ var newVideo = $("#line-" + lineNum + "-sharevideo"); |
|
8289 |
+ newVideo.prop("src", src); |
|
8290 |
+ newVideo.off("loadedmetadata"); |
|
8291 |
+ newVideo.on("loadedmetadata", function () { |
|
8292 |
+ console.log("Video can play now... "); |
|
8293 |
+ |
|
8294 |
+ // Resample Video |
|
8295 |
+ var ResampleSize = 360; |
|
8296 |
+ if(VideoResampleSize == "HD") ResampleSize = 720; |
|
8297 |
+ if(VideoResampleSize == "FHD") ResampleSize = 1080; |
|
8298 |
+ |
|
8299 |
+ var videoObj = newVideo.get(0); |
|
8300 |
+ var resampleCanvas = $('<canvas/>').get(0); |
|
8301 |
+ |
|
8302 |
+ var videoWidth = videoObj.videoWidth; |
|
8303 |
+ var videoHeight = videoObj.videoHeight; |
|
8304 |
+ if(videoWidth >= videoHeight){ |
|
8305 |
+ // Landscape / Square |
|
8306 |
+ if(videoHeight > ResampleSize){ |
|
8307 |
+ var p = ResampleSize / videoHeight; |
|
8308 |
+ videoHeight = ResampleSize; |
|
8309 |
+ videoWidth = videoWidth * p; |
|
8310 |
+ } |
|
8311 |
+ } |
|
8312 |
+ else { |
|
8313 |
+ // Portrate... (phone turned on its side) |
|
8314 |
+ if(videoWidth > ResampleSize){ |
|
8315 |
+ var p = ResampleSize / videoWidth; |
|
8316 |
+ videoWidth = ResampleSize; |
|
8317 |
+ videoHeight = videoHeight * p; |
|
8318 |
+ } |
|
8319 |
+ } |
|
8320 |
+ |
|
8321 |
+ resampleCanvas.width = videoWidth; |
|
8322 |
+ resampleCanvas.height = videoHeight; |
|
8323 |
+ var resampleContext = resampleCanvas.getContext("2d"); |
|
8324 |
+ |
|
8325 |
+ window.clearInterval(session.data.videoResampleInterval); |
|
8326 |
+ session.data.videoResampleInterval = window.setInterval(function(){ |
|
8327 |
+ resampleContext.drawImage(videoObj, 0, 0, videoWidth, videoHeight); |
|
8328 |
+ }, 40); // 25frames per second |
|
8329 |
+ |
|
8330 |
+ // Capture the streams |
|
8331 |
+ var videoMediaStream = null; |
|
8332 |
+ if('captureStream' in videoObj) { |
|
8333 |
+ videoMediaStream = videoObj.captureStream(); |
|
8334 |
+ } |
|
8335 |
+ else if('mozCaptureStream' in videoObj) { |
|
8336 |
+ // This doesn't really work |
|
8337 |
+ // see: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/captureStream |
|
8338 |
+ videoMediaStream = videoObj.mozCaptureStream(); |
|
8339 |
+ } |
|
8340 |
+ else { |
|
8341 |
+ // This is not supported. |
|
8342 |
+ // videoMediaStream = videoObj.webkitCaptureStream(); |
|
8343 |
+ console.warn("Cannot capture stream from video, this will result in no audio being transmitted.") |
|
8344 |
+ } |
|
8345 |
+ var resampleVideoMediaStream = resampleCanvas.captureStream(25); |
|
8346 |
+ |
|
8347 |
+ // Get the Tracks |
|
8348 |
+ var videoMediaTrack = resampleVideoMediaStream.getVideoTracks()[0]; |
|
8349 |
+ |
|
8350 |
+ var audioTrackFromVideo = (videoMediaStream != null )? videoMediaStream.getAudioTracks()[0] : null; |
|
8351 |
+ |
|
8352 |
+ // Switch & Merge Tracks |
|
8353 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
8354 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8355 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "video") { |
|
8356 |
+ console.log("Switching Track : "+ RTCRtpSender.track.label); |
|
8357 |
+ RTCRtpSender.track.stop(); |
|
8358 |
+ RTCRtpSender.replaceTrack(videoMediaTrack); |
|
8359 |
+ } |
|
8360 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
8361 |
+ console.log("Switching to mixed Audio track on session"); |
|
8362 |
+ |
|
8363 |
+ session.data.AudioSourceTrack = RTCRtpSender.track; |
|
8364 |
+ |
|
8365 |
+ var mixedAudioStream = new MediaStream(); |
|
8366 |
+ if(audioTrackFromVideo) mixedAudioStream.addTrack(audioTrackFromVideo); |
|
8367 |
+ mixedAudioStream.addTrack(RTCRtpSender.track); |
|
8368 |
+ var mixedAudioTrack = MixAudioStreams(mixedAudioStream).getAudioTracks()[0]; |
|
8369 |
+ mixedAudioTrack.IsMixedTrack = true; |
|
8370 |
+ |
|
8371 |
+ RTCRtpSender.replaceTrack(mixedAudioTrack); |
|
8372 |
+ } |
|
8373 |
+ }); |
|
8374 |
+ |
|
8375 |
+ // Set Preview |
|
8376 |
+ console.log("Showing as preview..."); |
|
8377 |
+ var localVideo = $("#line-" + lineNum + "-localVideo").get(0); |
|
8378 |
+ localVideo.srcObject = videoMediaStream; |
|
8379 |
+ localVideo.onloadedmetadata = function(e) { |
|
8380 |
+ localVideo.play().then(function(){ |
|
8381 |
+ console.log("Playing Preview Video File"); |
|
8382 |
+ }).catch(function(e){ |
|
8383 |
+ console.error("Cannot play back video", e); |
|
8384 |
+ }); |
|
8385 |
+ } |
|
8386 |
+ // Play the video |
|
8387 |
+ console.log("Starting Video..."); |
|
8388 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).play(); |
|
8389 |
+ }); |
|
8390 |
+ |
|
8391 |
+ $("#line-"+ lineNum +"-sharevideo").show(); |
|
8392 |
+ console.log("Video for Sharing created..."); |
|
8393 |
+} |
|
8394 |
+function ShareScreen(lineNum){ |
|
8395 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8396 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
8397 |
+ console.warn("Line or Session is Null"); |
|
8398 |
+ return; |
|
8399 |
+ } |
|
8400 |
+ var session = lineObj.SipSession; |
|
8401 |
+ |
|
8402 |
+ $("#line-" + lineNum + "-msg").html(lang.switching_to_shared_screeen); |
|
8403 |
+ |
|
8404 |
+ var localStream = new MediaStream(); |
|
8405 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
8406 |
+ |
|
8407 |
+ if (navigator.getDisplayMedia) { |
|
8408 |
+ // EDGE, legacy support |
|
8409 |
+ var screenShareConstraints = { video: true, audio: false } |
|
8410 |
+ navigator.getDisplayMedia(screenShareConstraints).then(function(newStream) { |
|
8411 |
+ console.log("navigator.getDisplayMedia") |
|
8412 |
+ var newMediaTrack = newStream.getVideoTracks()[0]; |
|
8413 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8414 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "video") { |
|
8415 |
+ console.log("Switching Video Track : "+ RTCRtpSender.track.label + " to Screen"); |
|
8416 |
+ RTCRtpSender.track.stop(); |
|
8417 |
+ RTCRtpSender.replaceTrack(newMediaTrack); |
|
8418 |
+ localStream.addTrack(newMediaTrack); |
|
8419 |
+ } |
|
8420 |
+ }); |
|
8421 |
+ |
|
8422 |
+ // Set Preview |
|
8423 |
+ // =========== |
|
8424 |
+ console.log("Showing as preview..."); |
|
8425 |
+ var localVideo = $("#line-" + lineNum + "-localVideo").get(0); |
|
8426 |
+ localVideo.srcObject = localStream; |
|
8427 |
+ localVideo.onloadedmetadata = function(e) { |
|
8428 |
+ localVideo.play(); |
|
8429 |
+ } |
|
8430 |
+ }).catch(function (err) { |
|
8431 |
+ console.error("Error on getUserMedia"); |
|
8432 |
+ }); |
|
8433 |
+ } |
|
8434 |
+ else if (navigator.mediaDevices.getDisplayMedia) { |
|
8435 |
+ // New standard |
|
8436 |
+ var screenShareConstraints = { video: true, audio: false } |
|
8437 |
+ navigator.mediaDevices.getDisplayMedia(screenShareConstraints).then(function(newStream) { |
|
8438 |
+ console.log("navigator.mediaDevices.getDisplayMedia") |
|
8439 |
+ var newMediaTrack = newStream.getVideoTracks()[0]; |
|
8440 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8441 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "video") { |
|
8442 |
+ console.log("Switching Video Track : "+ RTCRtpSender.track.label + " to Screen"); |
|
8443 |
+ RTCRtpSender.track.stop(); |
|
8444 |
+ RTCRtpSender.replaceTrack(newMediaTrack); |
|
8445 |
+ localStream.addTrack(newMediaTrack); |
|
8446 |
+ } |
|
8447 |
+ }); |
|
8448 |
+ |
|
8449 |
+ // Set Preview |
|
8450 |
+ // =========== |
|
8451 |
+ console.log("Showing as preview..."); |
|
8452 |
+ var localVideo = $("#line-" + lineNum + "-localVideo").get(0); |
|
8453 |
+ localVideo.srcObject = localStream; |
|
8454 |
+ localVideo.onloadedmetadata = function(e) { |
|
8455 |
+ localVideo.play(); |
|
8456 |
+ } |
|
8457 |
+ }).catch(function (err) { |
|
8458 |
+ console.error("Error on getUserMedia"); |
|
8459 |
+ }); |
|
8460 |
+ } |
|
8461 |
+ else { |
|
8462 |
+ // Firefox, apparently |
|
8463 |
+ var screenShareConstraints = { video: { mediaSource: 'screen' }, audio: false } |
|
8464 |
+ navigator.mediaDevices.getUserMedia(screenShareConstraints).then(function(newStream) { |
|
8465 |
+ console.log("navigator.mediaDevices.getUserMedia") |
|
8466 |
+ var newMediaTrack = newStream.getVideoTracks()[0]; |
|
8467 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8468 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "video") { |
|
8469 |
+ console.log("Switching Video Track : "+ RTCRtpSender.track.label + " to Screen"); |
|
8470 |
+ RTCRtpSender.track.stop(); |
|
8471 |
+ RTCRtpSender.replaceTrack(newMediaTrack); |
|
8472 |
+ localStream.addTrack(newMediaTrack); |
|
8473 |
+ } |
|
8474 |
+ }); |
|
8475 |
+ |
|
8476 |
+ // Set Preview |
|
8477 |
+ console.log("Showing as preview..."); |
|
8478 |
+ var localVideo = $("#line-" + lineNum + "-localVideo").get(0); |
|
8479 |
+ localVideo.srcObject = localStream; |
|
8480 |
+ localVideo.onloadedmetadata = function(e) { |
|
8481 |
+ localVideo.play(); |
|
8482 |
+ } |
|
8483 |
+ }).catch(function (err) { |
|
8484 |
+ console.error("Error on getUserMedia"); |
|
8485 |
+ }); |
|
8486 |
+ } |
|
8487 |
+ |
|
8488 |
+ // Restore Audio Stream if it was changed |
|
8489 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
8490 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8491 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
8492 |
+ RTCRtpSender.replaceTrack(session.data.AudioSourceTrack).then(function(){ |
|
8493 |
+ if(session.data.ismute){ |
|
8494 |
+ RTCRtpSender.track.enabled = false; |
|
8495 |
+ } |
|
8496 |
+ }).catch(function(){ |
|
8497 |
+ console.error(e); |
|
8498 |
+ }); |
|
8499 |
+ session.data.AudioSourceTrack = null; |
|
8500 |
+ } |
|
8501 |
+ }); |
|
8502 |
+ } |
|
8503 |
+ |
|
8504 |
+} |
|
8505 |
+function DisableVideoStream(lineNum){ |
|
8506 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8507 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
8508 |
+ console.warn("Line or Session is Null"); |
|
8509 |
+ return; |
|
8510 |
+ } |
|
8511 |
+ var session = lineObj.SipSession; |
|
8512 |
+ |
|
8513 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
8514 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
8515 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "video") { |
|
8516 |
+ console.log("Disable Video Track : "+ RTCRtpSender.track.label + ""); |
|
8517 |
+ RTCRtpSender.track.enabled = false; //stop(); |
|
8518 |
+ } |
|
8519 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
8520 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
8521 |
+ RTCRtpSender.replaceTrack(session.data.AudioSourceTrack).then(function(){ |
|
8522 |
+ if(session.data.ismute){ |
|
8523 |
+ RTCRtpSender.track.enabled = false; |
|
8524 |
+ } |
|
8525 |
+ }).catch(function(){ |
|
8526 |
+ console.error(e); |
|
8527 |
+ }); |
|
8528 |
+ session.data.AudioSourceTrack = null; |
|
8529 |
+ } |
|
8530 |
+ } |
|
8531 |
+ }); |
|
8532 |
+ |
|
8533 |
+ // Set Preview |
|
8534 |
+ console.log("Showing as preview..."); |
|
8535 |
+ var localVideo = $("#line-" + lineNum + "-localVideo").get(0); |
|
8536 |
+ localVideo.pause(); |
|
8537 |
+ localVideo.removeAttribute('src'); |
|
8538 |
+ localVideo.load(); |
|
8539 |
+ |
|
8540 |
+ $("#line-" + lineNum + "-msg").html(lang.video_disabled); |
|
8541 |
+} |
|
8542 |
+ |
|
8543 |
+// Phone Lines |
|
8544 |
+// =========== |
|
8545 |
+var Line = function(lineNumber, displayName, displayNumber, buddyObj){ |
|
8546 |
+ this.LineNumber = lineNumber; |
|
8547 |
+ this.DisplayName = displayName; |
|
8548 |
+ this.DisplayNumber = displayNumber; |
|
8549 |
+ this.IsSelected = false; |
|
8550 |
+ this.BuddyObj = buddyObj; |
|
8551 |
+ this.SipSession = null; |
|
8552 |
+ this.LocalSoundMeter = null; |
|
8553 |
+ this.RemoteSoundMeter = null; |
|
8554 |
+} |
|
8555 |
+function ShowDial(obj){ |
|
8556 |
+ |
|
8557 |
+ var leftPos = obj.offsetWidth + 104; |
|
8558 |
+ var rightPos = 0; |
|
8559 |
+ var topPos = obj.offsetHeight + 117; |
|
8560 |
+ |
|
8561 |
+ if ($(window).width() <= 915) { |
|
8562 |
+ leftPos = event.pageX + obj.offsetWidth - 120; |
|
8563 |
+ rightPos = 0; |
|
8564 |
+ topPos = event.pageY + obj.offsetHeight - 11; |
|
8565 |
+ } |
|
8566 |
+ |
|
8567 |
+ var html = "<div id=mainDialPad><div><input id=dialText class=dialTextInput oninput=\"handleDialInput(this, event)\" onkeydown=\"dialOnkeydown(event, this)\"></div>"; |
|
8568 |
+ html += "<table cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
8569 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"KeyPress('1');new Audio('sounds/dtmf.mp3').play();\"><div>1</div><span> </span></button></td>" |
|
8570 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('2');new Audio('sounds/dtmf.mp3').play();\"><div>2</div><span>ABC</span></button></td>" |
|
8571 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('3');new Audio('sounds/dtmf.mp3').play();\"><div>3</div><span>DEF</span></button></td></tr>"; |
|
8572 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"KeyPress('4');new Audio('sounds/dtmf.mp3').play();\"><div>4</div><span>GHI</span></button></td>" |
|
8573 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('5');new Audio('sounds/dtmf.mp3').play();\"><div>5</div><span>JKL</span></button></td>" |
|
8574 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('6');new Audio('sounds/dtmf.mp3').play();\"><div>6</div><span>MNO</span></button></td></tr>"; |
|
8575 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"KeyPress('7');new Audio('sounds/dtmf.mp3').play();\"><div>7</div><span>PQRS</span></button></td>" |
|
8576 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('8');new Audio('sounds/dtmf.mp3').play();\"><div>8</div><span>TUV</span></button></td>" |
|
8577 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('9');new Audio('sounds/dtmf.mp3').play();\"><div>9</div><span>WXYZ</span></button></td></tr>"; |
|
8578 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"KeyPress('*');new Audio('sounds/dtmf.mp3').play();\">*</button></td>" |
|
8579 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('0');new Audio('sounds/dtmf.mp3').play();\">0</button></td>" |
|
8580 |
+ html += "<td><button class=dtmfButtons onclick=\"KeyPress('#');new Audio('sounds/dtmf.mp3').play();\">#</button></td></tr>"; |
|
8581 |
+ html += "</table>"; |
|
8582 |
+ html += "<div style=\"text-align: center;\">"; |
|
8583 |
+ html += "<button class=\"roundButtons dialButtons\" id=dialAudio style=\"width:48px; height:48px;\" title=\""+ lang.audio_call +"\" onclick=\"DialByLine('audio')\"><i class=\"fa fa-phone\"></i></button>"; |
|
8584 |
+ if(EnableVideoCalling){ |
|
8585 |
+ html += "<button class=\"roundButtons dialButtons\" id=dialVideo style=\"width:48px; height:48px; margin-left:20px\" title=\""+ lang.video_call +"\" onclick=\"DialByLine('video')\"><i class=\"fa fa-video-camera\"></i></button>"; |
|
8586 |
+ } |
|
8587 |
+ html += "</div></div>"; |
|
8588 |
+ |
|
8589 |
+ $.jeegoopopup.open({ |
|
8590 |
+ html: html, |
|
8591 |
+ width: "auto", |
|
8592 |
+ height: "auto", |
|
8593 |
+ left: leftPos, |
|
8594 |
+ right: rightPos, |
|
8595 |
+ top: topPos, |
|
8596 |
+ scrolling: 'no', |
|
8597 |
+ skinClass: 'jg_popup_basic', |
|
8598 |
+// innerClass: 'showDialInner', |
|
8599 |
+ overlay: true, |
|
8600 |
+ opacity: 0, |
|
8601 |
+ draggable: true, |
|
8602 |
+ resizable: false, |
|
8603 |
+ fadeIn: 0 |
|
8604 |
+ }); |
|
8605 |
+ |
|
8606 |
+ $("#dialText").focus(); |
|
8607 |
+ |
|
8608 |
+ if ($(window).width() <= 915) { $.jeegoopopup.right(6); } else { $.jeegoopopup.width('auto').height('auto').left(leftPos).top(topPos); } |
|
8609 |
+ |
|
8610 |
+ $("#jg_popup_overlay").click(function() { $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); $.jeegoopopup.close(); }); |
|
8611 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); $.jeegoopopup.close(); } }); |
|
8612 |
+} |
|
8613 |
+ |
|
8614 |
+function handleDialInput(obj, event){ |
|
8615 |
+ if(EnableAlphanumericDial){ |
|
8616 |
+ $("#dialText").val($("#dialText").val().replace(/[^\da-zA-Z\*\#\+]/g, "").substring(0,MaxDidLength)); |
|
8617 |
+ } |
|
8618 |
+ else { |
|
8619 |
+ $("#dialText").val($("#dialText").val().replace(/[^\d\*\#\+]/g, "").substring(0,MaxDidLength)); |
|
8620 |
+ } |
|
8621 |
+ $("#dialVideo").prop('disabled', ($("#dialText").val().length >= DidLength)); |
|
8622 |
+} |
|
8623 |
+function dialOnkeydown(event, obj, buddy) { |
|
8624 |
+ var keycode = (event.keyCode ? event.keyCode : event.which); |
|
8625 |
+ if (keycode == '13'){ |
|
8626 |
+ |
|
8627 |
+ event.preventDefault(); |
|
8628 |
+ |
|
8629 |
+ // Defaults to audio dial |
|
8630 |
+ DialByLine('audio'); |
|
8631 |
+ |
|
8632 |
+ $("#jg_popup_b").empty(); $("#jg_popup_l").empty(); $("#windowCtrls").empty(); $.jeegoopopup.close(); |
|
8633 |
+ |
|
8634 |
+ return false; |
|
8635 |
+ } |
|
8636 |
+} |
|
8637 |
+function KeyPress(num){ |
|
8638 |
+ $("#dialText").val(($("#dialText").val()+num).substring(0,MaxDidLength)); |
|
8639 |
+ $("#dialVideo").prop('disabled', ($("#dialText").val().length >= DidLength)); |
|
8640 |
+} |
|
8641 |
+function DialByLine(type, buddy, numToDial, CallerID){ |
|
8642 |
+ $.jeegoopopup.close(); |
|
8643 |
+ if(userAgent == null || userAgent.isRegistered()==false){ |
|
8644 |
+ ConfigureExtensionWindow(); |
|
8645 |
+ return; |
|
8646 |
+ } |
|
8647 |
+ |
|
8648 |
+ var numDial = (numToDial)? numToDial : $("#dialText").val(); |
|
8649 |
+ if(EnableAlphanumericDial){ |
|
8650 |
+ numDial = numDial.replace(/[^\da-zA-Z\*\#\+]/g, "").substring(0,MaxDidLength); |
|
8651 |
+ } |
|
8652 |
+ else { |
|
8653 |
+ numDial = numDial.replace(/[^\d\*\#\+]/g, "").substring(0,MaxDidLength); |
|
8654 |
+ } |
|
8655 |
+ if(numDial.length == 0) { |
|
8656 |
+ console.warn("Enter number to dial"); |
|
8657 |
+ return; |
|
8658 |
+ } |
|
8659 |
+ |
|
8660 |
+ // Create a Buddy if one is not already existing |
|
8661 |
+ var buddyObj = (buddy)? FindBuddyByIdentity(buddy) : FindBuddyByDid(numDial); |
|
8662 |
+ if(buddyObj == null) { |
|
8663 |
+ var buddyType = (numDial.length > DidLength)? "contact" : "extension"; |
|
8664 |
+ // Assumption but anyway: If the number starts with a * or # then its probably not a subscribable DID, |
|
8665 |
+ // and is probably a feature code. |
|
8666 |
+ if(buddyType.substring(0,1) == "*" || buddyType.substring(0,1) == "#") buddyType = "contact"; |
|
8667 |
+ buddyObj = MakeBuddy(buddyType, true, false, true, (CallerID)? CallerID : numDial, numDial); |
|
8668 |
+ } |
|
8669 |
+ |
|
8670 |
+ // Create a Line |
|
8671 |
+ newLineNumber = newLineNumber + 1; |
|
8672 |
+ lineObj = new Line(newLineNumber, buddyObj.CallerIDName, numDial, buddyObj); |
|
8673 |
+ Lines.push(lineObj); |
|
8674 |
+ AddLineHtml(lineObj); |
|
8675 |
+ SelectLine(newLineNumber); |
|
8676 |
+ UpdateBuddyList(); |
|
8677 |
+ |
|
8678 |
+ // Start Call Invite |
|
8679 |
+ if(type == "audio"){ |
|
8680 |
+ AudioCall(lineObj, numDial); |
|
8681 |
+ } |
|
8682 |
+ else { |
|
8683 |
+ VideoCall(lineObj, numDial); |
|
8684 |
+ } |
|
8685 |
+ |
|
8686 |
+ try{ |
|
8687 |
+ $("#line-" + newLineNumber).get(0).scrollIntoViewIfNeeded(); |
|
8688 |
+ } catch(e){} |
|
8689 |
+} |
|
8690 |
+function SelectLine(lineNum){ |
|
8691 |
+ |
|
8692 |
+ $("#roundcubeFrame").remove(); |
|
8693 |
+ |
|
8694 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8695 |
+ if(lineObj == null) return; |
|
8696 |
+ |
|
8697 |
+ var displayLineNumber = 0; |
|
8698 |
+ for(var l = 0; l < Lines.length; l++) { |
|
8699 |
+ if(Lines[l].LineNumber == lineObj.LineNumber) displayLineNumber = l+1; |
|
8700 |
+ if(Lines[l].IsSelected == true && Lines[l].LineNumber == lineObj.LineNumber){ |
|
8701 |
+ // Nothing to do, you re-selected the same buddy; |
|
8702 |
+ return; |
|
8703 |
+ } |
|
8704 |
+ } |
|
8705 |
+ |
|
8706 |
+ console.log("Selecting Line : "+ lineObj.LineNumber); |
|
8707 |
+ |
|
8708 |
+ // Can only display one thing on the right |
|
8709 |
+ $(".streamSelected").each(function () { |
|
8710 |
+ $(this).prop('class', 'stream'); |
|
8711 |
+ }); |
|
8712 |
+ $("#line-ui-" + lineObj.LineNumber).prop('class', 'streamSelected'); |
|
8713 |
+ |
|
8714 |
+ $("#line-ui-" + lineObj.LineNumber + "-DisplayLineNo").html("<i class=\"fa fa-phone\"></i> "+ lang.line +" "+ displayLineNumber); |
|
8715 |
+ $("#line-ui-" + lineObj.LineNumber + "-LineIcon").html(displayLineNumber); |
|
8716 |
+ |
|
8717 |
+ // Switch the SIP Sessions |
|
8718 |
+ SwitchLines(lineObj.LineNumber); |
|
8719 |
+ |
|
8720 |
+ // Update Lines List |
|
8721 |
+ for(var l = 0; l < Lines.length; l++) { |
|
8722 |
+ var classStr = (Lines[l].LineNumber == lineObj.LineNumber)? "buddySelected" : "buddy"; |
|
8723 |
+ if(Lines[l].SipSession != null) classStr = (Lines[l].SipSession.local_hold)? "buddyActiveCallHollding" : "buddyActiveCall"; |
|
8724 |
+ |
|
8725 |
+ $("#line-" + Lines[l].LineNumber).prop('class', classStr); |
|
8726 |
+ Lines[l].IsSelected = (Lines[l].LineNumber == lineObj.LineNumber); |
|
8727 |
+ } |
|
8728 |
+ // Update Buddy List |
|
8729 |
+ for(var b = 0; b < Buddies.length; b++) { |
|
8730 |
+ $("#contact-" + Buddies[b].identity).prop("class", "buddy"); |
|
8731 |
+ Buddies[b].IsSelected = false; |
|
8732 |
+ } |
|
8733 |
+ |
|
8734 |
+ // Change to Stream if in Narrow view |
|
8735 |
+ UpdateUI(); |
|
8736 |
+} |
|
8737 |
+function FindLineByNumber(lineNum) { |
|
8738 |
+ for(var l = 0; l < Lines.length; l++) { |
|
8739 |
+ if(Lines[l].LineNumber == lineNum) return Lines[l]; |
|
8740 |
+ } |
|
8741 |
+ return null; |
|
8742 |
+} |
|
8743 |
+function AddLineHtml(lineObj) { |
|
8744 |
+ |
|
8745 |
+ var html = "<table id=\"line-ui-"+ lineObj.LineNumber +"\" class=\"stream\" cellspacing=\"5\" cellpadding=\"0\">"; |
|
8746 |
+ html += "<tr><td class=streamSection>"; |
|
8747 |
+ |
|
8748 |
+ // Close|Return|Back Button |
|
8749 |
+ html += "<div style=\"float:left; margin:0px; padding:5px; height:38px; line-height:38px\">" |
|
8750 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-back\" onclick=\"CloseLine('"+ lineObj.LineNumber +"')\" class=roundButtons title=\""+ lang.back +"\"><i class=\"fa fa-chevron-left\"></i></button> "; |
|
8751 |
+ html += "</div>" |
|
8752 |
+ |
|
8753 |
+ // Profile UI |
|
8754 |
+ html += "<div class=contact style=\"float: left;\">"; |
|
8755 |
+ html += "<div id=\"line-ui-"+ lineObj.LineNumber +"-LineIcon\" class=lineIcon>"+ lineObj.LineNumber +"</div>"; |
|
8756 |
+ html += "<div id=\"line-ui-"+ lineObj.LineNumber +"-DisplayLineNo\" class=contactNameText><i class=\"fa fa-phone\"></i> "+ lang.line +" "+ lineObj.LineNumber +"</div>"; |
|
8757 |
+ |
|
8758 |
+ html += "<div class=presenceText>"+ lineObj.DisplayName +" <"+ lineObj.DisplayNumber +"></div>"; |
|
8759 |
+ html += "</div>"; |
|
8760 |
+ |
|
8761 |
+ // Action Buttons |
|
8762 |
+ html += "<div style=\"float:right; line-height: 46px;\">"; |
|
8763 |
+ html += "</div>"; |
|
8764 |
+ |
|
8765 |
+ // Separator -------------------------------------------------------------------------- |
|
8766 |
+ html += "<div style=\"clear:both; height:0px\"></div>" |
|
8767 |
+ |
|
8768 |
+ // Calling UI -------------------------------------------------------------------------- |
|
8769 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-calling\">"; |
|
8770 |
+ |
|
8771 |
+ // Gneral Messages |
|
8772 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-timer\" style=\"float: right; margin-top: 4px; margin-right: 10px; color: #575757; display:none;\"></div>"; |
|
8773 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-msg\" class=callStatus style=\"display:none\">...</div>"; |
|
8774 |
+ |
|
8775 |
+ // Dialing Out Progress |
|
8776 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-progress\" style=\"display:none; margin-top: 10px\">"; |
|
8777 |
+ html += "<div class=progressCall>"; |
|
8778 |
+ html += "<button onclick=\"cancelSession('"+ lineObj.LineNumber +"')\" class=hangupButton><i class=\"fa fa-phone\"></i> "+ lang.cancel +"</button>"; |
|
8779 |
+ html += "</div>"; |
|
8780 |
+ html += "</div>"; |
|
8781 |
+ |
|
8782 |
+ // Active Call UI |
|
8783 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-ActiveCall\" style=\"display:none; margin-top: 10px;\">"; |
|
8784 |
+ |
|
8785 |
+ // Group Call |
|
8786 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-conference\" style=\"display:none;\"></div>"; |
|
8787 |
+ |
|
8788 |
+ // Video UI |
|
8789 |
+ if(lineObj.BuddyObj.type == "extension") { |
|
8790 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-VideoCall\" class=videoCall style=\"display:none;\">"; |
|
8791 |
+ |
|
8792 |
+ // Presentation |
|
8793 |
+ html += "<div style=\"height:35px; line-height:35px; text-align: right\">"+ lang.present +": "; |
|
8794 |
+ html += "<div class=pill-nav style=\"border-color:#333333\">"; |
|
8795 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-src-camera\" onclick=\"PresentCamera('"+ lineObj.LineNumber +"')\" title=\""+ lang.camera +"\" disabled><i class=\"fa fa-video-camera\"></i></button>"; |
|
8796 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-src-canvas\" onclick=\"PresentScratchpad('"+ lineObj.LineNumber +"')\" title=\""+ lang.scratchpad +"\"><i class=\"fa fa-pencil-square\"></i></button>"; |
|
8797 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-src-desktop\" onclick=\"PresentScreen('"+ lineObj.LineNumber +"')\" title=\""+ lang.screen +"\"><i class=\"fa fa-desktop\"></i></button>"; |
|
8798 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-src-video\" onclick=\"PresentVideo('"+ lineObj.LineNumber +"')\" title=\""+ lang.video +"\"><i class=\"fa fa-file-video-o\"></i></button>"; |
|
8799 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-src-blank\" onclick=\"PresentBlank('"+ lineObj.LineNumber +"')\" title=\""+ lang.blank +"\"><i class=\"fa fa-ban\"></i></button>"; |
|
8800 |
+ html += "</div>"; |
|
8801 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-expand\" onclick=\"ExpandVideoArea('"+ lineObj.LineNumber +"')\"><i class=\"fa fa-expand\"></i></button>"; |
|
8802 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-restore\" onclick=\"RestoreVideoArea('"+ lineObj.LineNumber +"')\" style=\"display:none\"><i class=\"fa fa-compress\"></i></button>"; |
|
8803 |
+ html += "</div>"; |
|
8804 |
+ |
|
8805 |
+ // Preview |
|
8806 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-preview-container\" class=PreviewContainer>"; |
|
8807 |
+ html += "<video id=\"line-"+ lineObj.LineNumber +"-localVideo\" muted></video>"; // Default Display |
|
8808 |
+ html += "</div>"; |
|
8809 |
+ |
|
8810 |
+ // Stage |
|
8811 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-stage-container\" class=StageContainer>"; |
|
8812 |
+ html += "<video id=\"line-"+ lineObj.LineNumber +"-remoteVideo\" muted></video>"; // Default Display |
|
8813 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-scratchpad-container\" style=\"display:none\"></div>"; |
|
8814 |
+ html += "<video id=\"line-"+ lineObj.LineNumber +"-sharevideo\" controls muted style=\"display:none; object-fit: contain;\"></video>"; |
|
8815 |
+ html += "</div>"; |
|
8816 |
+ |
|
8817 |
+ html += "</div>"; |
|
8818 |
+ } |
|
8819 |
+ |
|
8820 |
+ // Audio Call |
|
8821 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-AudioCall\" style=\"display:none;\">"; |
|
8822 |
+ html += "<audio id=\"line-"+ lineObj.LineNumber+"-remoteAudio\"></audio>"; |
|
8823 |
+ html += "</div>"; |
|
8824 |
+ |
|
8825 |
+ // In Call Buttons |
|
8826 |
+ html += "<div style=\"text-align:center\">"; |
|
8827 |
+ html += "<div style=\"margin-top:10px\">"; |
|
8828 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-ShowDtmf\" onclick=\"ShowDtmfMenu(this, '"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.show_key_pad +"\"><i class=\"fa fa-keyboard-o\"></i></button>"; |
|
8829 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-Mute\" onclick=\"MuteSession('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.mute +"\"><i class=\"fa fa-microphone-slash\"></i></button>"; |
|
8830 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-Unmute\" onclick=\"UnmuteSession('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.unmute +"\" style=\"color: red; display:none\"><i class=\"fa fa-microphone\"></i></button>"; |
|
8831 |
+ if(typeof MediaRecorder != "undefined" && (CallRecordingPolicy == "allow" || CallRecordingPolicy == "enabled")){ |
|
8832 |
+ // Safari: must enable in Develop > Experimental Features > MediaRecorder |
|
8833 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-start-recording\" onclick=\"StartRecording('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.start_call_recording +"\"><i class=\"fa fa-dot-circle-o\"></i></button>"; |
|
8834 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-stop-recording\" onclick=\"StopRecording('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.stop_call_recording +"\" style=\"color: red; display:none\"><i class=\"fa fa-circle\"></i></button>"; |
|
8835 |
+ } |
|
8836 |
+ if(EnableTransfer){ |
|
8837 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-Transfer\" onclick=\"StartTransferSession('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.transfer_call +"\"><i class=\"fa fa-reply\" style=\"transform: rotateY(180deg)\"></i></button>"; |
|
8838 |
+ html += "<button id=\"line-"+ lineObj.LineNumber+"-btn-CancelTransfer\" onclick=\"CancelTransferSession('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.cancel_transfer +"\" style=\"color: red; display:none\"><i class=\"fa fa-reply\" style=\"transform: rotateY(180deg)\"></i></button>"; |
|
8839 |
+ } |
|
8840 |
+ |
|
8841 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-Hold\" onclick=\"holdSession('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.hold_call +"\"><i class=\"fa fa-pause-circle\"></i></button>"; |
|
8842 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-Unhold\" onclick=\"unholdSession('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons\" title=\""+ lang.resume_call +"\" style=\"color: red; display:none\"><i class=\"fa fa-play-circle\"></i></button>"; |
|
8843 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-End\" onclick=\"endSession('"+ lineObj.LineNumber +"')\" class=\"roundButtons inCallButtons hangupButton\" title=\""+ lang.end_call +"\"><i class=\"fa fa-phone\"></i></button>"; |
|
8844 |
+ html += "</div>"; |
|
8845 |
+ // Call Transfer |
|
8846 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-Transfer\" style=\"display:none\">"; |
|
8847 |
+ html += "<div style=\"margin-top:10px\">"; |
|
8848 |
+ html += "<span class=searchClean><input id=\"line-"+ lineObj.LineNumber +"-txt-FindTransferBuddy\" oninput=\"QuickFindBuddy(this,'"+ lineObj.LineNumber +"')\" type=text autocomplete=none style=\"width:150px;\" autocomplete=none placeholder=\""+ lang.search_or_enter_number +"\"></span>"; |
|
8849 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-blind-transfer\" onclick=\"BlindTransfer('"+ lineObj.LineNumber +"')\"><i class=\"fa fa-reply\" style=\"transform: rotateY(180deg)\"></i> "+ lang.blind_transfer +"</button>" |
|
8850 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-attended-transfer\" onclick=\"AttendedTransfer('"+ lineObj.LineNumber +"')\"><i class=\"fa fa-reply-all\" style=\"transform: rotateY(180deg)\"></i> "+ lang.attended_transfer +"</button>"; |
|
8851 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-complete-attended-transfer\" style=\"display:none\"><i class=\"fa fa-reply-all\" style=\"transform: rotateY(180deg)\"></i> "+ lang.complete_transfer +"</buuton>"; |
|
8852 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-cancel-attended-transfer\" style=\"display:none\"><i class=\"fa fa-phone\" style=\"transform: rotate(135deg);\"></i> "+ lang.cancel_transfer +"</buuton>"; |
|
8853 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-terminate-attended-transfer\" style=\"display:none\"><i class=\"fa fa-phone\" style=\"transform: rotate(135deg);\"></i> "+ lang.end_transfer_call +"</buuton>"; |
|
8854 |
+ html += "</div>"; |
|
8855 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-transfer-status\" class=callStatus style=\"margin-top:10px; display:none\">...</div>"; |
|
8856 |
+ html += "<audio id=\"line-"+ lineObj.LineNumber +"-transfer-remoteAudio\" style=\"display:none\"></audio>"; |
|
8857 |
+ html += "</div>"; |
|
8858 |
+ // Call Conference |
|
8859 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-Conference\" style=\"display:none\">"; |
|
8860 |
+ html += "<div style=\"margin-top:10px\">"; |
|
8861 |
+ html += "<span class=searchClean><input id=\"line-"+ lineObj.LineNumber +"-txt-FindConferenceBuddy\" oninput=\"QuickFindBuddy(this,'"+ lineObj.LineNumber +"')\" type=text autocomplete=none style=\"width:150px;\" autocomplete=none placeholder=\""+ lang.search_or_enter_number +"\"></span>"; |
|
8862 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-conference-dial\" onclick=\"ConferenceDial('"+ lineObj.LineNumber +"')\"><i class=\"fa fa-phone\"></i> "+ lang.call +"</button>"; |
|
8863 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-cancel-conference-dial\" style=\"display:none\"><i class=\"fa fa-phone\"></i> "+ lang.cancel_call +"</buuton>"; |
|
8864 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-join-conference-call\" style=\"display:none\"><i class=\"fa fa-users\"></i> "+ lang.join_conference_call +"</buuton>"; |
|
8865 |
+ html += " <button id=\"line-"+ lineObj.LineNumber +"-btn-terminate-conference-call\" style=\"display:none\"><i class=\"fa fa-phone\"></i> "+ lang.end_conference_call +"</buuton>"; |
|
8866 |
+ html += "</div>"; |
|
8867 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-conference-status\" class=callStatus style=\"margin-top:10px; display:none\">...</div>"; |
|
8868 |
+ html += "<audio id=\"line-"+ lineObj.LineNumber +"-conference-remoteAudio\" style=\"display:none\"></audio>"; |
|
8869 |
+ html += "</div>"; |
|
8870 |
+ |
|
8871 |
+ // Monitoring |
|
8872 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-monitoring\" style=\"margin-top:10px;margin-bottom:10px;\">"; |
|
8873 |
+ html += "<span style=\"vertical-align: middle\"><i class=\"fa fa-microphone\"></i></span> "; |
|
8874 |
+ html += "<span class=meterContainer title=\""+ lang.microphone_levels +"\">"; |
|
8875 |
+ html += "<span id=\"line-"+ lineObj.LineNumber +"-Mic\" class=meterLevel style=\"height:0%\"></span>"; |
|
8876 |
+ html += "</span> "; |
|
8877 |
+ html += "<span style=\"vertical-align: middle\"><i class=\"fa fa-volume-up\"></i></span> "; |
|
8878 |
+ html += "<span class=meterContainer title=\""+ lang.speaker_levels +"\">"; |
|
8879 |
+ html += "<span id=\"line-"+ lineObj.LineNumber +"-Speaker\" class=meterLevel style=\"height:0%\"></span>"; |
|
8880 |
+ html += "</span> "; |
|
8881 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-btn-settings\" onclick=\"ChangeSettings('"+ lineObj.LineNumber +"', this)\"><i class=\"fa fa-cogs\"></i> "+ lang.device_settings +"</button>"; |
|
8882 |
+ html += "<button id=\"line-"+ lineObj.LineNumber +"-call-stats\" onclick=\"ShowCallStats('"+ lineObj.LineNumber +"', this)\"><i class=\"fa fa-area-chart\"></i> "+ lang.call_stats +"</button>"; |
|
8883 |
+ html += "</div>"; |
|
8884 |
+ |
|
8885 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-AudioStats\" class=\"audioStats cleanScroller\" style=\"display:none\">"; |
|
8886 |
+ html += "<div style=\"text-align:right\"><button onclick=\"HideCallStats('"+ lineObj.LineNumber +"', this)\"><i class=\"fa fa-times\" style=\"font-size:20px;\"></i></button></div>"; |
|
8887 |
+ html += "<fieldset class=audioStatsSet onclick=\"HideCallStats('"+ lineObj.LineNumber +"', this)\">"; |
|
8888 |
+ html += "<legend>"+ lang.send_statistics +"</legend>"; |
|
8889 |
+ html += "<canvas id=\"line-"+ lineObj.LineNumber +"-AudioSendBitRate\" class=audioGraph width=600 height=160 style=\"width:600px; height:160px\"></canvas>"; |
|
8890 |
+ html += "<canvas id=\"line-"+ lineObj.LineNumber +"-AudioSendPacketRate\" class=audioGraph width=600 height=160 style=\"width:600px; height:160px\"></canvas>"; |
|
8891 |
+ html += "</fieldset>"; |
|
8892 |
+ html += "<fieldset class=audioStatsSet onclick=\"HideCallStats('"+ lineObj.LineNumber +"', this)\">"; |
|
8893 |
+ html += "<legend>"+ lang.receive_statistics +"</legend>"; |
|
8894 |
+ html += "<canvas id=\"line-"+ lineObj.LineNumber +"-AudioReceiveBitRate\" class=audioGraph width=600 height=160 style=\"width:600px; height:160px\"></canvas>"; |
|
8895 |
+ html += "<canvas id=\"line-"+ lineObj.LineNumber +"-AudioReceivePacketRate\" class=audioGraph width=600 height=160 style=\"width:600px; height:160px\"></canvas>"; |
|
8896 |
+ html += "<canvas id=\"line-"+ lineObj.LineNumber +"-AudioReceivePacketLoss\" class=audioGraph width=600 height=160 style=\"width:600px; height:160px\"></canvas>"; |
|
8897 |
+ html += "<canvas id=\"line-"+ lineObj.LineNumber +"-AudioReceiveJitter\" class=audioGraph width=600 height=160 style=\"width:600px; height:160px\"></canvas>"; |
|
8898 |
+ html += "<canvas id=\"line-"+ lineObj.LineNumber +"-AudioReceiveLevels\" class=audioGraph width=600 height=160 style=\"width:600px; height:160px\"></canvas>"; |
|
8899 |
+ html += "</fieldset>"; |
|
8900 |
+ html += "</div>"; |
|
8901 |
+ |
|
8902 |
+ html += "</div>"; |
|
8903 |
+ html += "</div>"; |
|
8904 |
+ html += "</div>"; |
|
8905 |
+ html += "</td></tr>"; |
|
8906 |
+ html += "<tr><td class=\"streamSection streamSectionBackground\">"; |
|
8907 |
+ |
|
8908 |
+ html += "<div id=\"line-"+ lineObj.LineNumber +"-CallDetails\" class=\"chatHistory cleanScroller\">"; |
|
8909 |
+ // In Call Activity |
|
8910 |
+ html += "</div>"; |
|
8911 |
+ |
|
8912 |
+ html += "</td></tr>"; |
|
8913 |
+ html += "</table>"; |
|
8914 |
+ |
|
8915 |
+ $("#rightContent").append(html); |
|
8916 |
+} |
|
8917 |
+function RemoveLine(lineObj){ |
|
8918 |
+ if(lineObj == null) return; |
|
8919 |
+ |
|
8920 |
+ for(var l = 0; l < Lines.length; l++) { |
|
8921 |
+ if(Lines[l].LineNumber == lineObj.LineNumber) { |
|
8922 |
+ Lines.splice(l,1); |
|
8923 |
+ break; |
|
8924 |
+ } |
|
8925 |
+ } |
|
8926 |
+ |
|
8927 |
+ CloseLine(lineObj.LineNumber); |
|
8928 |
+ $("#line-ui-"+ lineObj.LineNumber).remove(); |
|
8929 |
+ |
|
8930 |
+ UpdateBuddyList(); |
|
8931 |
+ |
|
8932 |
+ // Rather than showing nothing, go to the last buddy selected |
|
8933 |
+ // Select last user |
|
8934 |
+ if(localDB.getItem("SelectedBuddy") != null){ |
|
8935 |
+ console.log("Selecting previously selected buddy...", localDB.getItem("SelectedBuddy")); |
|
8936 |
+ SelectBuddy(localDB.getItem("SelectedBuddy")); |
|
8937 |
+ UpdateUI(); |
|
8938 |
+ } |
|
8939 |
+} |
|
8940 |
+function CloseLine(lineNum){ |
|
8941 |
+ // Lines and Buddies (Left) |
|
8942 |
+ $(".buddySelected").each(function () { |
|
8943 |
+ $(this).prop('class', 'buddy'); |
|
8944 |
+ }); |
|
8945 |
+ // Streams (Right) |
|
8946 |
+ $(".streamSelected").each(function () { |
|
8947 |
+ $(this).prop('class', 'stream'); |
|
8948 |
+ }); |
|
8949 |
+ |
|
8950 |
+ SwitchLines(0); |
|
8951 |
+ |
|
8952 |
+ console.log("Closing Line: "+ lineNum); |
|
8953 |
+ for(var l = 0; l < Lines.length; l++){ |
|
8954 |
+ Lines[l].IsSelected = false; |
|
8955 |
+ } |
|
8956 |
+ selectedLine = null; |
|
8957 |
+ for(var b = 0; b < Buddies.length; b++){ |
|
8958 |
+ Buddies[b].IsSelected = false; |
|
8959 |
+ } |
|
8960 |
+ selectedBuddy = null; |
|
8961 |
+ |
|
8962 |
+ $.jeegoopopup.close(); |
|
8963 |
+ |
|
8964 |
+ // Change to Stream if in Narrow view |
|
8965 |
+ UpdateUI(); |
|
8966 |
+} |
|
8967 |
+function SwitchLines(lineNum){ |
|
8968 |
+ $.each(userAgent.sessions, function (i, session) { |
|
8969 |
+ // All the other calls, not on hold |
|
8970 |
+ if(session.local_hold == false && session.data.line != lineNum) { |
|
8971 |
+ console.log("Putting an active call on hold: Line: "+ session.data.line +" buddy: "+ session.data.buddyId); |
|
8972 |
+ session.hold(); // Check state |
|
8973 |
+ |
|
8974 |
+ // Log Hold |
|
8975 |
+ if(!session.data.hold) session.data.hold = []; |
|
8976 |
+ session.data.hold.push({ event: "hold", eventTime: utcDateNow() }); |
|
8977 |
+ } |
|
8978 |
+ $("#line-" + session.data.line + "-btn-Hold").hide(); |
|
8979 |
+ $("#line-" + session.data.line + "-btn-Unhold").show(); |
|
8980 |
+ session.data.IsCurrentCall = false; |
|
8981 |
+ }); |
|
8982 |
+ |
|
8983 |
+ var lineObj = FindLineByNumber(lineNum); |
|
8984 |
+ if(lineObj != null && lineObj.SipSession != null) { |
|
8985 |
+ var session = lineObj.SipSession; |
|
8986 |
+ if(session.local_hold == true) { |
|
8987 |
+ console.log("Taking call off hold: Line: "+ lineNum +" buddy: "+ session.data.buddyId); |
|
8988 |
+ session.unhold(); |
|
8989 |
+ |
|
8990 |
+ // Log Hold |
|
8991 |
+ if(!session.data.hold) session.data.hold = []; |
|
8992 |
+ session.data.hold.push({ event: "unhold", eventTime: utcDateNow() }); |
|
8993 |
+ } |
|
8994 |
+ $("#line-" + lineNum + "-btn-Hold").show(); |
|
8995 |
+ $("#line-" + lineNum + "-btn-Unhold").hide(); |
|
8996 |
+ session.data.IsCurrentCall = true; |
|
8997 |
+ } |
|
8998 |
+ selectedLine = lineNum; |
|
8999 |
+ |
|
9000 |
+ RefreshLineActivity(lineNum); |
|
9001 |
+} |
|
9002 |
+function RefreshLineActivity(lineNum){ |
|
9003 |
+ var lineObj = FindLineByNumber(lineNum); |
|
9004 |
+ if(lineObj == null || lineObj.SipSession == null) { |
|
9005 |
+ return; |
|
9006 |
+ } |
|
9007 |
+ var session = lineObj.SipSession; |
|
9008 |
+ |
|
9009 |
+ $("#line-"+ lineNum +"-CallDetails").empty(); |
|
9010 |
+ |
|
9011 |
+ var callDetails = []; |
|
9012 |
+ |
|
9013 |
+ var ringTime = 0; |
|
9014 |
+ var CallStart = moment.utc(session.data.callstart.replace(" UTC", "")); |
|
9015 |
+ var CallAnswer = null; |
|
9016 |
+ if(session.startTime){ |
|
9017 |
+ CallAnswer = moment.utc(session.startTime); |
|
9018 |
+ ringTime = moment.duration(CallAnswer.diff(CallStart)); |
|
9019 |
+ } |
|
9020 |
+ CallStart = CallStart.format("YYYY-MM-DD HH:mm:ss UTC") |
|
9021 |
+ CallAnswer = (CallAnswer)? CallAnswer.format("YYYY-MM-DD HH:mm:ss UTC") : null, |
|
9022 |
+ ringTime = (ringTime != 0)? ringTime.asSeconds() : 0 |
|
9023 |
+ |
|
9024 |
+ var srcCallerID = ""; |
|
9025 |
+ var dstCallerID = ""; |
|
9026 |
+ if(session.data.calldirection == "inbound") { |
|
9027 |
+ srcCallerID = "<"+ session.remoteIdentity.uri.user +"> "+ session.remoteIdentity.displayName; |
|
9028 |
+ } |
|
9029 |
+ else if(session.data.calldirection == "outbound") { |
|
9030 |
+ dstCallerID = session.remoteIdentity.uri.user; |
|
9031 |
+ } |
|
9032 |
+ |
|
9033 |
+ var withVideo = (session.data.withvideo)? "("+ lang.with_video +")" : ""; |
|
9034 |
+ var startCallMessage = (session.data.calldirection == "inbound")? lang.you_received_a_call_from + " " + srcCallerID +" "+ withVideo : lang.you_made_a_call_to + " " + dstCallerID +" "+ withVideo; |
|
9035 |
+ callDetails.push({ |
|
9036 |
+ Message: startCallMessage, |
|
9037 |
+ TimeStr : CallStart |
|
9038 |
+ }); |
|
9039 |
+ if(CallAnswer){ |
|
9040 |
+ var answerCallMessage = (session.data.calldirection == "inbound")? lang.you_answered_after + " " + ringTime + " " + lang.seconds_plural : lang.they_answered_after + " " + ringTime + " " + lang.seconds_plural; |
|
9041 |
+ callDetails.push({ |
|
9042 |
+ Message: answerCallMessage, |
|
9043 |
+ TimeStr : CallAnswer |
|
9044 |
+ }); |
|
9045 |
+ } |
|
9046 |
+ |
|
9047 |
+ var Transfers = (session.data.transfer)? session.data.transfer : []; |
|
9048 |
+ $.each(Transfers, function(item, transfer){ |
|
9049 |
+ var msg = (transfer.type == "Blind")? lang.you_started_a_blind_transfer_to +" "+ transfer.to +". " : lang.you_started_an_attended_transfer_to + " "+ transfer.to +". "; |
|
9050 |
+ if(transfer.accept && transfer.accept.complete == true){ |
|
9051 |
+ msg += lang.the_call_was_completed |
|
9052 |
+ } |
|
9053 |
+ else if(transfer.accept.disposition != "") { |
|
9054 |
+ msg += lang.the_call_was_not_completed +" ("+ transfer.accept.disposition +")" |
|
9055 |
+ } |
|
9056 |
+ callDetails.push({ |
|
9057 |
+ Message : msg, |
|
9058 |
+ TimeStr : transfer.transferTime |
|
9059 |
+ }); |
|
9060 |
+ }); |
|
9061 |
+ var Mutes = (session.data.mute)? session.data.mute : [] |
|
9062 |
+ $.each(Mutes, function(item, mute){ |
|
9063 |
+ callDetails.push({ |
|
9064 |
+ Message : (mute.event == "mute")? lang.you_put_the_call_on_mute : lang.you_took_the_call_off_mute, |
|
9065 |
+ TimeStr : mute.eventTime |
|
9066 |
+ }); |
|
9067 |
+ }); |
|
9068 |
+ var Holds = (session.data.hold)? session.data.hold : [] |
|
9069 |
+ $.each(Holds, function(item, hold){ |
|
9070 |
+ callDetails.push({ |
|
9071 |
+ Message : (hold.event == "hold")? lang.you_put_the_call_on_hold : lang.you_took_the_call_off_hold, |
|
9072 |
+ TimeStr : hold.eventTime |
|
9073 |
+ }); |
|
9074 |
+ }); |
|
9075 |
+ var Recordings = (session.data.recordings)? session.data.recordings : [] |
|
9076 |
+ $.each(Recordings, function(item, recording){ |
|
9077 |
+ var msg = lang.call_is_being_recorded; |
|
9078 |
+ if(recording.startTime != recording.stopTime){ |
|
9079 |
+ msg += "("+ lang.now_stopped +")" |
|
9080 |
+ } |
|
9081 |
+ callDetails.push({ |
|
9082 |
+ Message : msg, |
|
9083 |
+ TimeStr : recording.startTime |
|
9084 |
+ }); |
|
9085 |
+ }); |
|
9086 |
+ var ConfCalls = (session.data.confcalls)? session.data.confcalls : [] |
|
9087 |
+ $.each(ConfCalls, function(item, confCall){ |
|
9088 |
+ var msg = lang.you_started_a_conference_call_to +" "+ confCall.to +". "; |
|
9089 |
+ if(confCall.accept && confCall.accept.complete == true){ |
|
9090 |
+ msg += lang.the_call_was_completed |
|
9091 |
+ } |
|
9092 |
+ else if(confCall.accept.disposition != "") { |
|
9093 |
+ msg += lang.the_call_was_not_completed +" ("+ confCall.accept.disposition +")" |
|
9094 |
+ } |
|
9095 |
+ callDetails.push({ |
|
9096 |
+ Message : msg, |
|
9097 |
+ TimeStr : confCall.startTime |
|
9098 |
+ }); |
|
9099 |
+ }); |
|
9100 |
+ |
|
9101 |
+ callDetails.sort(function(a, b){ |
|
9102 |
+ var aMo = moment.utc(a.TimeStr.replace(" UTC", "")); |
|
9103 |
+ var bMo = moment.utc(b.TimeStr.replace(" UTC", "")); |
|
9104 |
+ if (aMo.isSameOrAfter(bMo, "second")) { |
|
9105 |
+ return -1; |
|
9106 |
+ } else return 1; |
|
9107 |
+ return 0; |
|
9108 |
+ }); |
|
9109 |
+ |
|
9110 |
+ $.each(callDetails, function(item, detail){ |
|
9111 |
+ var Time = moment.utc(detail.TimeStr.replace(" UTC", "")).local().format(DisplayTimeFormat); |
|
9112 |
+ var messageString = "<table class=timelineMessage cellspacing=0 cellpadding=0><tr>" |
|
9113 |
+ messageString += "<td class=timelineMessageArea>" |
|
9114 |
+ messageString += "<div class=timelineMessageDate><i class=\"fa fa-circle timelineMessageDot\"></i>"+ Time +"</div>" |
|
9115 |
+ messageString += "<div class=timelineMessageText>"+ detail.Message +"</div>" |
|
9116 |
+ messageString += "</td>" |
|
9117 |
+ messageString += "</tr></table>"; |
|
9118 |
+ $("#line-"+ lineNum +"-CallDetails").prepend(messageString); |
|
9119 |
+ }); |
|
9120 |
+} |
|
9121 |
+ |
|
9122 |
+// Buddy & Contacts |
|
9123 |
+// ================ |
|
9124 |
+var Buddy = function(type, identity, CallerIDName, ExtNo, MobileNumber, ContactNumber1, ContactNumber2, lastActivity, desc, Email){ |
|
9125 |
+ this.type = type; // extension | contact | group |
|
9126 |
+ this.identity = identity; |
|
9127 |
+ this.CallerIDName = CallerIDName; |
|
9128 |
+ this.Email = Email; |
|
9129 |
+ this.Desc = desc; |
|
9130 |
+ this.ExtNo = ExtNo; |
|
9131 |
+ this.MobileNumber = MobileNumber; |
|
9132 |
+ this.ContactNumber1 = ContactNumber1; |
|
9133 |
+ this.ContactNumber2 = ContactNumber2; |
|
9134 |
+ this.lastActivity = lastActivity; // Full Date as string eg "1208-03-21 15:34:23 UTC" |
|
9135 |
+ this.devState = "dotOffline"; |
|
9136 |
+ this.presence = "Unknown"; |
|
9137 |
+ this.missed = 0; |
|
9138 |
+ this.IsSelected = false; |
|
9139 |
+ this.imageObjectURL = ""; |
|
9140 |
+} |
|
9141 |
+function InitUserBuddies(){ |
|
9142 |
+ var template = { TotalRows:0, DataCollection:[] } |
|
9143 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(template)); |
|
9144 |
+ return JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
9145 |
+} |
|
9146 |
+function MakeBuddy(type, update, focus, subscribe, callerID, did){ |
|
9147 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
9148 |
+ if(json == null) json = InitUserBuddies(); |
|
9149 |
+ |
|
9150 |
+ var buddyObj = null; |
|
9151 |
+ if(type == "contact"){ |
|
9152 |
+ var id = uID(); |
|
9153 |
+ var dateNow = utcDateNow(); |
|
9154 |
+ json.DataCollection.push({ |
|
9155 |
+ Type: "contact", |
|
9156 |
+ LastActivity: dateNow, |
|
9157 |
+ ExtensionNumber: "", |
|
9158 |
+ MobileNumber: "", |
|
9159 |
+ ContactNumber1: did, |
|
9160 |
+ ContactNumber2: "", |
|
9161 |
+ uID: null, |
|
9162 |
+ cID: id, |
|
9163 |
+ gID: null, |
|
9164 |
+ DisplayName: callerID, |
|
9165 |
+ Position: "", |
|
9166 |
+ Description: "", |
|
9167 |
+ Email: "", |
|
9168 |
+ MemberCount: 0 |
|
9169 |
+ }); |
|
9170 |
+ buddyObj = new Buddy("contact", id, callerID, "", "", did, "", dateNow, "", ""); |
|
9171 |
+ AddBuddy(buddyObj, update, focus); |
|
9172 |
+ } |
|
9173 |
+ else { |
|
9174 |
+ var id = uID(); |
|
9175 |
+ var dateNow = utcDateNow(); |
|
9176 |
+ json.DataCollection.push({ |
|
9177 |
+ Type: "extension", |
|
9178 |
+ LastActivity: dateNow, |
|
9179 |
+ ExtensionNumber: did, |
|
9180 |
+ MobileNumber: "", |
|
9181 |
+ ContactNumber1: "", |
|
9182 |
+ ContactNumber2: "", |
|
9183 |
+ uID: id, |
|
9184 |
+ cID: null, |
|
9185 |
+ gID: null, |
|
9186 |
+ DisplayName: callerID, |
|
9187 |
+ Position: "", |
|
9188 |
+ Description: "", |
|
9189 |
+ Email: "", |
|
9190 |
+ MemberCount: 0 |
|
9191 |
+ }); |
|
9192 |
+ buddyObj = new Buddy("extension", id, callerID, did, "", "", "", dateNow, "", ""); |
|
9193 |
+ AddBuddy(buddyObj, update, focus, subscribe); |
|
9194 |
+ } |
|
9195 |
+ // Update Size: |
|
9196 |
+ json.TotalRows = json.DataCollection.length; |
|
9197 |
+ |
|
9198 |
+ // Save To DB |
|
9199 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
9200 |
+ |
|
9201 |
+ // Return new buddy |
|
9202 |
+ return buddyObj; |
|
9203 |
+} |
|
9204 |
+function UpdateBuddyCalerID(buddyObj, callerID){ |
|
9205 |
+ buddyObj.CallerIDName = callerID; |
|
9206 |
+ |
|
9207 |
+ var buddy = buddyObj.identity; |
|
9208 |
+ // Update DB |
|
9209 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
9210 |
+ if(json != null){ |
|
9211 |
+ $.each(json.DataCollection, function (i, item) { |
|
9212 |
+ if(item.uID == buddy || item.cID == buddy || item.gID == buddy){ |
|
9213 |
+ item.DisplayName = callerID; |
|
9214 |
+ return false; |
|
9215 |
+ } |
|
9216 |
+ }); |
|
9217 |
+ // Save To DB |
|
9218 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
9219 |
+ } |
|
9220 |
+ |
|
9221 |
+ UpdateBuddyList(); |
|
9222 |
+} |
|
9223 |
+function AddBuddy(buddyObj, update, focus, subscribe){ |
|
9224 |
+ Buddies.push(buddyObj); |
|
9225 |
+ if(update == true) UpdateBuddyList(); |
|
9226 |
+ AddBuddyMessageStream(buddyObj); |
|
9227 |
+ if(subscribe == true) SubscribeBuddy(buddyObj); |
|
9228 |
+ if(focus == true) SelectBuddy(buddyObj.identity); |
|
9229 |
+} |
|
9230 |
+function PopulateBuddyList() { |
|
9231 |
+ console.log("Clearing Buddies..."); |
|
9232 |
+ Buddies = new Array(); |
|
9233 |
+ console.log("Adding Buddies..."); |
|
9234 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
9235 |
+ if(json == null) return; |
|
9236 |
+ |
|
9237 |
+ console.log("Total Buddies: " + json.TotalRows); |
|
9238 |
+ $.each(json.DataCollection, function (i, item) { |
|
9239 |
+ if(item.Type == "extension"){ |
|
9240 |
+ // extension |
|
9241 |
+ var buddy = new Buddy("extension", item.uID, item.DisplayName, item.ExtensionNumber, item.MobileNumber, item.ContactNumber1, item.ContactNumber2, item.LastActivity, item.Position, item.Email); |
|
9242 |
+ AddBuddy(buddy, false, false); |
|
9243 |
+ } |
|
9244 |
+ else if(item.Type == "contact"){ |
|
9245 |
+ // contact |
|
9246 |
+ var buddy = new Buddy("contact", item.cID, item.DisplayName, "", item.MobileNumber, item.ContactNumber1, item.ContactNumber2, item.LastActivity, item.Description, item.Email); |
|
9247 |
+ AddBuddy(buddy, false, false); |
|
9248 |
+ } |
|
9249 |
+ else if(item.Type == "group"){ |
|
9250 |
+ // group |
|
9251 |
+ var buddy = new Buddy("group", item.gID, item.DisplayName, item.ExtensionNumber, "", "", "", item.LastActivity, item.MemberCount + " member(s)", item.Email); |
|
9252 |
+ AddBuddy(buddy, false, false); |
|
9253 |
+ } |
|
9254 |
+ }); |
|
9255 |
+ |
|
9256 |
+ // Update List (after add) |
|
9257 |
+ console.log("Updating Buddy List..."); |
|
9258 |
+ UpdateBuddyList(); |
|
9259 |
+} |
|
9260 |
+function UpdateBuddyList(){ |
|
9261 |
+ var filter = $("#txtFindBuddy").val(); |
|
9262 |
+ |
|
9263 |
+ $("#myContacts").empty(); |
|
9264 |
+ |
|
9265 |
+ var callCount = 0 |
|
9266 |
+ for(var l = 0; l < Lines.length; l++) { |
|
9267 |
+ |
|
9268 |
+ var classStr = (Lines[l].IsSelected)? "buddySelected" : "buddy"; |
|
9269 |
+ if(Lines[l].SipSession != null) classStr = (Lines[l].SipSession.local_hold)? "buddyActiveCallHollding" : "buddyActiveCall"; |
|
9270 |
+ |
|
9271 |
+ var html = "<div id=\"line-"+ Lines[l].LineNumber +"\" class="+ classStr +" onclick=\"SelectLine('"+ Lines[l].LineNumber +"')\">"; |
|
9272 |
+ html += "<div class=lineIcon>"+ (l + 1) +"</div>"; |
|
9273 |
+ html += "<div class=contactNameText><i class=\"fa fa-phone\"></i> "+ lang.line +" "+ (l + 1) +"</div>"; |
|
9274 |
+ html += "<div id=\"Line-"+ Lines[l].ExtNo +"-datetime\" class=contactDate> </div>"; |
|
9275 |
+ html += "<div class=presenceText>"+ Lines[l].DisplayName +" <"+ Lines[l].DisplayNumber +">" +"</div>"; |
|
9276 |
+ html += "</div>"; |
|
9277 |
+ // SIP.Session.C.STATUS_TERMINATED |
|
9278 |
+ if(Lines[l].SipSession && Lines[l].SipSession.data.earlyReject != true){ |
|
9279 |
+ $("#myContacts").append(html); |
|
9280 |
+ callCount ++; |
|
9281 |
+ } |
|
9282 |
+ } |
|
9283 |
+ |
|
9284 |
+ // Sort and shuffle Buddy List |
|
9285 |
+ // =========================== |
|
9286 |
+ Buddies.sort(function(a, b){ |
|
9287 |
+ var aMo = moment.utc(a.lastActivity.replace(" UTC", "")); |
|
9288 |
+ var bMo = moment.utc(b.lastActivity.replace(" UTC", "")); |
|
9289 |
+ if (aMo.isSameOrAfter(bMo, "second")) { |
|
9290 |
+ return -1; |
|
9291 |
+ } else return 1; |
|
9292 |
+ return 0; |
|
9293 |
+ }); |
|
9294 |
+ |
|
9295 |
+ |
|
9296 |
+ for(var b = 0; b < Buddies.length; b++) { |
|
9297 |
+ var buddyObj = Buddies[b]; |
|
9298 |
+ |
|
9299 |
+ if(filter && filter.length >= 1){ |
|
9300 |
+ // Perform Filter Display |
|
9301 |
+ var display = false; |
|
9302 |
+ if(buddyObj.CallerIDName.toLowerCase().indexOf(filter.toLowerCase()) > -1 ) display = true; |
|
9303 |
+ if(buddyObj.ExtNo.toLowerCase().indexOf(filter.toLowerCase()) > -1 ) display = true; |
|
9304 |
+ if(buddyObj.Desc.toLowerCase().indexOf(filter.toLowerCase()) > -1 ) display = true; |
|
9305 |
+ if(!display) continue; |
|
9306 |
+ } |
|
9307 |
+ |
|
9308 |
+ var today = moment.utc(); |
|
9309 |
+ var lastActivity = moment.utc(buddyObj.lastActivity.replace(" UTC", "")); |
|
9310 |
+ var displayDateTime = ""; |
|
9311 |
+ if(lastActivity.isSame(today, 'day')) |
|
9312 |
+ { |
|
9313 |
+ displayDateTime = lastActivity.local().format(DisplayTimeFormat); |
|
9314 |
+ } |
|
9315 |
+ else { |
|
9316 |
+ displayDateTime = lastActivity.local().format(DisplayDateFormat); |
|
9317 |
+ } |
|
9318 |
+ |
|
9319 |
+ var classStr = (buddyObj.IsSelected)? "buddySelected" : "buddy"; |
|
9320 |
+ if(buddyObj.type == "extension") { |
|
9321 |
+ var friendlyState = buddyObj.presence; |
|
9322 |
+ if (friendlyState == "Unknown") friendlyState = lang.state_unknown; |
|
9323 |
+ if (friendlyState == "Not online") friendlyState = lang.state_not_online; |
|
9324 |
+ if (friendlyState == "Ready") friendlyState = lang.state_ready; |
|
9325 |
+ if (friendlyState == "On the phone") friendlyState = lang.state_on_the_phone; |
|
9326 |
+ if (friendlyState == "Ringing") friendlyState = lang.state_ringing; |
|
9327 |
+ if (friendlyState == "On hold") friendlyState = lang.state_on_hold; |
|
9328 |
+ if (friendlyState == "Unavailable") friendlyState = lang.state_unavailable; |
|
9329 |
+ |
|
9330 |
+ // An extension on the same system |
|
9331 |
+ var html = "<div id=\"contact-"+ buddyObj.identity +"\" class="+ classStr +" onmouseenter=\"ShowBuddyDial(this, '"+ buddyObj.identity +"')\" onmouseleave=\"HideBuddyDial(this, '"+ buddyObj.identity +"')\" onclick=\"SelectBuddy('"+ buddyObj.identity +"', 'extension')\">"; |
|
9332 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-devstate\" class=\""+ buddyObj.devState +"\"></span>"; |
|
9333 |
+ if (getDbItem("useRoundcube", "") == 1 && buddyObj.Email != '' && buddyObj.Email != null && typeof buddyObj.Email != 'undefined') { |
|
9334 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-email\" class=quickDial style=\"right: 66px; display:none\" title='"+ lang.send_email +"' onclick=\"ComposeEmail('"+ buddyObj.identity +"', this, event)\"><i class=\"fa fa-envelope-o\" aria-hidden=\"true\"></i></span>"; |
|
9335 |
+ } |
|
9336 |
+ if (EnableVideoCalling) { |
|
9337 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-audio-dial\" class=quickDial style=\"right: 44px; display:none\" title='"+ lang.audio_call +"' onclick=\"QuickDialAudio('"+ buddyObj.identity +"', this, event)\"><i class=\"fa fa-phone\"></i></span>"; |
|
9338 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-video-dial\" class=quickDial style=\"right: 23px; display:none\" title='"+ lang.video_call +"' onclick=\"QuickDialVideo('"+ buddyObj.identity +"', '"+ buddyObj.ExtNo +"', event)\"><i class=\"fa fa-video-camera\"></i></span>"; |
|
9339 |
+ } else { |
|
9340 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-audio-dial\" class=quickDial style=\"right: 23px; display:none\" title='"+ lang.audio_call +"' onclick=\"QuickDialAudio('"+ buddyObj.identity +"', this, event)\"><i class=\"fa fa-phone\"></i></span>"; |
|
9341 |
+ } |
|
9342 |
+ if(buddyObj.missed && buddyObj.missed > 0){ |
|
9343 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-missed\" class=missedNotifyer>"+ buddyObj.missed +"</span>"; |
|
9344 |
+ } |
|
9345 |
+ else{ |
|
9346 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-missed\" class=missedNotifyer style=\"display:none\">"+ buddyObj.missed +"</span>"; |
|
9347 |
+ } |
|
9348 |
+ html += "<div class=buddyIcon onclick=\"EditBuddyWindow('"+ buddyObj.identity +"')\" style=\"background-image: url('"+ getPicture(buddyObj.identity) +"')\" title=\"Edit Contact\"><i class=\"fa fa-pencil-square-o\" aria-hidden=\"true\"></i></div>"; |
|
9349 |
+ html += "<div class=contactNameText><i class=\"fa fa-phone-square\"></i> "+ buddyObj.ExtNo +" - "+ buddyObj.CallerIDName +"</div>"; |
|
9350 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-datetime\" class=contactDate>"+ displayDateTime +"</div>"; |
|
9351 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-presence\" class=presenceText>"+ friendlyState +"</div>"; |
|
9352 |
+ html += "</div>"; |
|
9353 |
+ $("#myContacts").append(html); |
|
9354 |
+ } else if(buddyObj.type == "contact") { |
|
9355 |
+ // An Addressbook Contact |
|
9356 |
+ var html = "<div id=\"contact-"+ buddyObj.identity +"\" class="+ classStr +" onmouseenter=\"ShowBuddyDial(this, '"+ buddyObj.identity +"')\" onmouseleave=\"HideBuddyDial(this, '"+ buddyObj.identity +"')\" onclick=\"SelectBuddy('"+ buddyObj.identity +"', 'contact')\">"; |
|
9357 |
+ if (getDbItem("useRoundcube", "") == 1 && buddyObj.Email != '' && buddyObj.Email != null && typeof buddyObj.Email != 'undefined') { |
|
9358 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-email\" class=quickDial style=\"right: 44px; display:none\" title='"+ lang.send_email +"' onclick=\"ComposeEmail('"+ buddyObj.identity +"', this, event)\"><i class=\"fa fa-envelope-o\" aria-hidden=\"true\"></i></span>"; |
|
9359 |
+ } |
|
9360 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-audio-dial\" class=quickDial style=\"right: 23px; display:none\" title='"+ lang.audio_call +"' onclick=\"QuickDialAudio('"+ buddyObj.identity +"', this, event)\"><i class=\"fa fa-phone\"></i></span>"; |
|
9361 |
+ if(buddyObj.missed && buddyObj.missed > 0){ |
|
9362 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-missed\" class=missedNotifyer>"+ buddyObj.missed +"</span>"; |
|
9363 |
+ } |
|
9364 |
+ else{ |
|
9365 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-missed\" class=missedNotifyer style=\"display:none\">"+ buddyObj.missed +"</span>"; |
|
9366 |
+ } |
|
9367 |
+ html += "<div class=buddyIcon onclick=\"EditBuddyWindow('"+ buddyObj.identity +"')\" style=\"background-image: url('"+ getPicture(buddyObj.identity,"contact") +"')\" title=\"Edit Contact\"><i class=\"fa fa-pencil-square-o\" aria-hidden=\"true\"></i></div>"; |
|
9368 |
+ html += "<div class=contactNameText><i class=\"fa fa-address-card\"></i> "+ buddyObj.CallerIDName +"</div>"; |
|
9369 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-datetime\" class=contactDate>"+ displayDateTime +"</div>"; |
|
9370 |
+ html += "<div class=presenceText>"+ buddyObj.Desc +"</div>"; |
|
9371 |
+ html += "</div>"; |
|
9372 |
+ $("#myContacts").append(html); |
|
9373 |
+ } else if(buddyObj.type == "group"){ |
|
9374 |
+ // A collection of extensions and contacts |
|
9375 |
+ var html = "<div id=\"contact-"+ buddyObj.identity +"\" class="+ classStr +" onmouseenter=\"ShowBuddyDial(this, '"+ buddyObj.identity +"')\" onmouseleave=\"HideBuddyDial(this, '"+ buddyObj.identity +"')\" onclick=\"SelectBuddy('"+ buddyObj.identity +"', 'group')\">"; |
|
9376 |
+ if (getDbItem("useRoundcube", "") == 1 && buddyObj.Email != '' && buddyObj.Email != null && typeof buddyObj.Email != 'undefined') { |
|
9377 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-email\" class=quickDial style=\"right: 44px; display:none\" title='"+ lang.send_email +"' onclick=\"ComposeEmail('"+ buddyObj.identity +"', this, event)\"><i class=\"fa fa-envelope-o\" aria-hidden=\"true\"></i></span>"; |
|
9378 |
+ } |
|
9379 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-audio-dial\" class=quickDial style=\"right: 23px; display:none\" title='"+ lang.audio_call +"' onclick=\"QuickDialAudio('"+ buddyObj.identity +"', this, event)\"><i class=\"fa fa-phone\"></i></span>"; |
|
9380 |
+ if(buddyObj.missed && buddyObj.missed > 0){ |
|
9381 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-missed\" class=missedNotifyer>"+ buddyObj.missed +"</span>"; |
|
9382 |
+ } |
|
9383 |
+ else{ |
|
9384 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-missed\" class=missedNotifyer style=\"display:none\">"+ buddyObj.missed +"</span>"; |
|
9385 |
+ } |
|
9386 |
+ html += "<div class=buddyIcon onclick=\"EditBuddyWindow('"+ buddyObj.identity +"')\" style=\"background-image: url('"+ getPicture(buddyObj.identity,"group") +"')\" title=\"Edit Contact\"><i class=\"fa fa-pencil-square-o\" aria-hidden=\"true\"></i></div>"; |
|
9387 |
+ html += "<div class=contactNameText><i class=\"fa fa-users\"></i> "+ buddyObj.CallerIDName +"</div>"; |
|
9388 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-datetime\" class=contactDate>"+ displayDateTime +"</div>"; |
|
9389 |
+ html += "<div class=presenceText>"+ buddyObj.Desc +"</div>"; |
|
9390 |
+ html += "</div>"; |
|
9391 |
+ $("#myContacts").append(html); |
|
9392 |
+ } |
|
9393 |
+ } |
|
9394 |
+} |
|
9395 |
+function AddBuddyMessageStream(buddyObj) { |
|
9396 |
+ var html = "<table id=\"stream-"+ buddyObj.identity +"\" class=stream cellspacing=5 cellpadding=0>"; |
|
9397 |
+ html += "<tr><td class=streamSection style=\"height: 48px;\">"; |
|
9398 |
+ |
|
9399 |
+ // Close|Return|Back Button |
|
9400 |
+ html += "<div style=\"float:left; margin:8.7px 0px 0px 8.7px; width: 38px; height:38px; line-height:38px;\">" |
|
9401 |
+ |
|
9402 |
+ html += "<button id=\"contact-"+ buddyObj.identity +"-btn-back\" onclick=\"CloseBuddy('"+ buddyObj.identity +"')\" class=roundButtons title=\""+ lang.back +"\"><i class=\"fa fa-chevron-left\"></i></button> "; |
|
9403 |
+ html += "</div>" |
|
9404 |
+ |
|
9405 |
+ // Profile UI |
|
9406 |
+ html += "<div class=contact style=\"float: left; position: absolute; left: 47px; right: 190px;\" onclick=\"ShowBuddyProfileMenu('"+ buddyObj.identity +"', this, '"+ buddyObj.type +"')\">"; |
|
9407 |
+ if(buddyObj.type == "extension") { |
|
9408 |
+ html += "<span id=\"contact-"+ buddyObj.identity +"-devstate-main\" class=\""+ buddyObj.devState +"\"></span>"; |
|
9409 |
+ } |
|
9410 |
+ if(buddyObj.type == "extension") { |
|
9411 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-picture-main\" class=buddyIcon style=\"background-image: url('"+ getPicture(buddyObj.identity) +"')\"></div>"; |
|
9412 |
+ } |
|
9413 |
+ else if(buddyObj.type == "contact") { |
|
9414 |
+ html += "<div class=buddyIcon style=\"background-image: url('"+ getPicture(buddyObj.identity,"contact") +"')\"></div>"; |
|
9415 |
+ } |
|
9416 |
+ else if(buddyObj.type == "group") { |
|
9417 |
+ html += "<div class=buddyIcon style=\"background-image: url('"+ getPicture(buddyObj.identity,"group") +"')\"></div>"; |
|
9418 |
+ } |
|
9419 |
+ if(buddyObj.type == "extension") { |
|
9420 |
+ html += "<div class=contactNameText style=\"margin-right: 0px;\"><i class=\"fa fa-phone-square\"></i> "+ buddyObj.ExtNo +" - "+ buddyObj.CallerIDName +"</div>"; |
|
9421 |
+ } |
|
9422 |
+ else if(buddyObj.type == "contact") { |
|
9423 |
+ html += "<div class=contactNameText style=\"margin-right: 0px;\"><i class=\"fa fa-address-card\"></i> "+ buddyObj.CallerIDName +"</div>"; |
|
9424 |
+ } |
|
9425 |
+ else if(buddyObj.type == "group") { |
|
9426 |
+ html += "<div class=contactNameText style=\"margin-right: 0px;\"><i class=\"fa fa-users\"></i> "+ buddyObj.CallerIDName +"</div>"; |
|
9427 |
+ } |
|
9428 |
+ if(buddyObj.type == "extension") { |
|
9429 |
+ var friendlyState = buddyObj.presence; |
|
9430 |
+ if (friendlyState == "Unknown") friendlyState = lang.state_unknown; |
|
9431 |
+ if (friendlyState == "Not online") friendlyState = lang.state_not_online; |
|
9432 |
+ if (friendlyState == "Ready") friendlyState = lang.state_ready; |
|
9433 |
+ if (friendlyState == "On the phone") friendlyState = lang.state_on_the_phone; |
|
9434 |
+ if (friendlyState == "Ringing") friendlyState = lang.state_ringing; |
|
9435 |
+ if (friendlyState == "On hold") friendlyState = lang.state_on_hold; |
|
9436 |
+ if (friendlyState == "Unavailable") friendlyState = lang.state_unavailable; |
|
9437 |
+ |
|
9438 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-presence-main\" class=presenceText>"+ friendlyState +"</div>"; |
|
9439 |
+ } else{ |
|
9440 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-presence-main\" class=presenceText>"+ buddyObj.Desc +"</div>"; |
|
9441 |
+ } |
|
9442 |
+ html += "</div>"; |
|
9443 |
+ |
|
9444 |
+ // Action Buttons |
|
9445 |
+ html += "<div style=\"float:right; line-height:46px; margin:3.2px 5px 0px 0px;\">"; |
|
9446 |
+ html += "<button id=\"contact-"+ buddyObj.identity +"-btn-audioCall\" onclick=\"AudioCallMenu('"+ buddyObj.identity +"', this)\" class=roundButtons title=\""+ lang.audio_call +"\"><i class=\"fa fa-phone\"></i></button> "; |
|
9447 |
+ if(buddyObj.type == "extension" && EnableVideoCalling) { |
|
9448 |
+ html += "<button id=\"contact-"+ buddyObj.identity +"-btn-videoCall\" onclick=\"DialByLine('video', '"+ buddyObj.identity +"', '"+ buddyObj.ExtNo +"');\" class=roundButtons title=\""+ lang.video_call +"\"><i class=\"fa fa-video-camera\"></i></button> "; |
|
9449 |
+ } |
|
9450 |
+ html += "<button id=\"contact-"+ buddyObj.identity +"-btn-search\" onclick=\"FindSomething('"+ buddyObj.identity +"')\" class=roundButtons title=\""+ lang.find_something +"\"><i class=\"fa fa-search\"></i></button> "; |
|
9451 |
+ if(buddyObj.type == "extension") { |
|
9452 |
+ html += "<button id=\"contact-"+ buddyObj.identity +"-btn-download-chat\" onclick=\"DownloadChatText('"+ buddyObj.identity +"')\" class=roundButtons title=\""+ lang.save_chat_text +"\"><i class=\"fa fa-download\" aria-hidden=\"true\"></i></button> "; |
|
9453 |
+ } |
|
9454 |
+ html += "<button id=\"contact-"+ buddyObj.identity +"-btn-remove\" onclick=\"RemoveBuddy('"+ buddyObj.identity +"')\" class=roundButtons title=\""+ lang.remove_contact +"\"><i class=\"fa fa-trash\"></i></button> "; |
|
9455 |
+ html += "</div>"; |
|
9456 |
+ |
|
9457 |
+ // Separator -------------------------------------------------------------------------- |
|
9458 |
+ html += "<div style=\"clear:both; height:0px\"></div>" |
|
9459 |
+ |
|
9460 |
+ // Calling UI -------------------------------------------------------------------------- |
|
9461 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-calling\">"; |
|
9462 |
+ |
|
9463 |
+ // Gneral Messages |
|
9464 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-timer\" style=\"float: right; margin-top: 4px; margin-right: 10px; color: #575757; display:none;\"></div>"; |
|
9465 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-msg\" class=callStatus style=\"display:none\">...</div>"; |
|
9466 |
+ |
|
9467 |
+ // Call Answer UI |
|
9468 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-AnswerCall\" class=answerCall style=\"display:none\">"; |
|
9469 |
+ html += "<div>"; |
|
9470 |
+ html += "<button onclick=\"AnswerAudioCall('"+ buddyObj.identity +"')\" class=answerButton><i class=\"fa fa-phone\"></i> "+ lang.answer_call +"</button> "; |
|
9471 |
+ if(buddyObj.type == "extension" && EnableVideoCalling) { |
|
9472 |
+ html += "<button id=\"contact-"+ buddyObj.identity +"-answer-video\" onclick=\"AnswerVideoCall('"+ buddyObj.identity +"')\" class=answerButton><i class=\"fa fa-video-camera\"></i> "+ lang.answer_call_with_video +"</button> "; |
|
9473 |
+ } |
|
9474 |
+ html += "<button onclick=\"RejectCall('"+ buddyObj.identity +"')\" class=hangupButton><i class=\"fa fa-phone\"></i> "+ lang.reject_call +"</button> "; |
|
9475 |
+ html += "</div>"; |
|
9476 |
+ html += "</div>"; |
|
9477 |
+ |
|
9478 |
+ html += "</div>"; |
|
9479 |
+ |
|
9480 |
+ // Search & Related Elements |
|
9481 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-search\" style=\"margin-top:6px; display:none\">"; |
|
9482 |
+ html += "<span class=searchClean style=\"width:100%; margin-left:9px;\"><input type=text style=\"width:40%;margin-bottom:5px;\" autocomplete=none oninput=SearchStream(this,'"+ buddyObj.identity +"') placeholder=\""+ lang.find_something_in_the_message_stream +"\"></span>"; |
|
9483 |
+ |
|
9484 |
+ html += "</div>"; |
|
9485 |
+ |
|
9486 |
+ html += "</td></tr>"; |
|
9487 |
+ html += "<tr><td class=\"streamSection streamSectionBackground\">"; |
|
9488 |
+ |
|
9489 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-ChatHistory\" class=\"chatHistory cleanScroller\" ondragenter=\"setupDragDrop(event, '"+ buddyObj.identity +"')\" ondragover=\"setupDragDrop(event, '"+ buddyObj.identity +"')\" ondragleave=\"cancelDragDrop(event, '"+ buddyObj.identity +"')\" ondrop=\"onFileDragDrop(event, '"+ buddyObj.identity +"')\">"; |
|
9490 |
+ // Previous Chat messages |
|
9491 |
+ html += "</div>"; |
|
9492 |
+ |
|
9493 |
+ html += "</td></tr>"; |
|
9494 |
+ |
|
9495 |
+ if ((buddyObj.type == "extension" || buddyObj.type == "group") && EnableTextMessaging) { |
|
9496 |
+ |
|
9497 |
+ html += "<tr><td id=sendChatMessageSection class=streamSection style=\"height:110px\">"; |
|
9498 |
+ |
|
9499 |
+ // Send Paste Image |
|
9500 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-imagePastePreview\" class=sendImagePreview style=\"display:none\" tabindex=0></div>"; |
|
9501 |
+ |
|
9502 |
+ // Send File |
|
9503 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-fileShare\" style=\"display:none\">"; |
|
9504 |
+ html += "<input type=file multiple onchange=\"console.log(this)\" />"; |
|
9505 |
+ html += "</div>"; |
|
9506 |
+ |
|
9507 |
+ // Send Audio Recording |
|
9508 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-audio-recording\" style=\"display:none\"></div>"; |
|
9509 |
+ |
|
9510 |
+ // Send Video Recording |
|
9511 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-video-recording\" style=\"display:none\"></div>"; |
|
9512 |
+ |
|
9513 |
+ // Dictate Message |
|
9514 |
+ // html += "<div id=\"contact-"+ buddyObj.identity +"-dictate-message\" style=\"display:none\"></div>"; |
|
9515 |
+ |
|
9516 |
+ // Emoji Menu Bar |
|
9517 |
+ html += "<div id=\"contact-"+ buddyObj.identity +"-emoji-menu\" style=\"display:none\" class=\"EmojiMenu\"></div>"; |
|
9518 |
+ |
|
9519 |
+ // ===================================== |
|
9520 |
+ // Type Area |
|
9521 |
+ html += "<table class=sendMessageContainer cellpadding=0 cellspacing=0><tr>"; |
|
9522 |
+ html += "<td><textarea id=\"contact-"+ buddyObj.identity +"-ChatMessage\" class=\"chatMessage\" placeholder=\""+ lang.type_your_message_here +"\" onkeydown=\"chatOnkeydown(event, this,'"+ buddyObj.identity +"')\" onpaste=\"chatOnbeforepaste(event, this,'"+ buddyObj.identity +"')\"></textarea></td>"; |
|
9523 |
+ html += "<td style=\"width:40px;padding-top:4px;\"><button onclick=\"SendChatMessage('"+ buddyObj.identity +"')\" class=roundButtonsSpec title=\""+ lang.send_chat_message +"\"><i class=\"fa fa-paper-plane-o\" aria-hidden=\"true\"></i></button>"; |
|
9524 |
+ html += "<button onclick=\"ShowEmojiBar('"+ buddyObj.identity +"')\" class=roundButtonsSpec title=\""+ lang.select_expression + "\"><i class=\"fa fa-smile-o\"></i></button>"; |
|
9525 |
+ html += "<button onclick=\"SendFile('"+ buddyObj.identity +"')\" class=roundButtonsSpec title=\""+ lang.send_file + "\"><i class=\"fa fa-file-text-o\"></i></button></td>"; |
|
9526 |
+ html += "</tr></table>"; |
|
9527 |
+ html += "</td></tr>"; |
|
9528 |
+ } |
|
9529 |
+ |
|
9530 |
+ html += "</table>"; |
|
9531 |
+ |
|
9532 |
+ $("#rightContent").append(html); |
|
9533 |
+} |
|
9534 |
+function RemoveBuddyMessageStream(buddyObj){ |
|
9535 |
+ CloseBuddy(buddyObj.identity); |
|
9536 |
+ |
|
9537 |
+ UpdateBuddyList(); |
|
9538 |
+ |
|
9539 |
+ // Remove Stream |
|
9540 |
+ $("#stream-"+ buddyObj.identity).remove(); |
|
9541 |
+ var stream = JSON.parse(localDB.getItem(buddyObj.identity + "-stream")); |
|
9542 |
+ localDB.removeItem(buddyObj.identity + "-stream"); |
|
9543 |
+ |
|
9544 |
+ // Remove Buddy |
|
9545 |
+ var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); |
|
9546 |
+ var x = 0; |
|
9547 |
+ $.each(json.DataCollection, function (i, item) { |
|
9548 |
+ if(item.uID == buddyObj.identity || item.cID == buddyObj.identity || item.gID == buddyObj.identity){ |
|
9549 |
+ x = i; |
|
9550 |
+ return false; |
|
9551 |
+ } |
|
9552 |
+ }); |
|
9553 |
+ json.DataCollection.splice(x,1); |
|
9554 |
+ json.TotalRows = json.DataCollection.length; |
|
9555 |
+ localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); |
|
9556 |
+ |
|
9557 |
+ // Remove Images |
|
9558 |
+ localDB.removeItem("img-"+ buddyObj.identity +"-extension"); |
|
9559 |
+ localDB.removeItem("img-"+ buddyObj.identity +"-contact"); |
|
9560 |
+ localDB.removeItem("img-"+ buddyObj.identity +"-group"); |
|
9561 |
+ |
|
9562 |
+ // Remove Call Recordings |
|
9563 |
+ if(stream && stream.DataCollection && stream.DataCollection.length >= 1){ |
|
9564 |
+ DeleteCallRecordings(buddyObj.identity, stream); |
|
9565 |
+ } |
|
9566 |
+ |
|
9567 |
+ // Remove QOS Data |
|
9568 |
+ DeleteQosData(buddyObj.identity); |
|
9569 |
+} |
|
9570 |
+function DeleteCallRecordings(buddy, stream){ |
|
9571 |
+ var indexedDB = window.indexedDB; |
|
9572 |
+ var request = indexedDB.open("CallRecordings"); |
|
9573 |
+ request.onerror = function(event) { |
|
9574 |
+ console.error("IndexDB Request Error:", event); |
|
9575 |
+ } |
|
9576 |
+ request.onupgradeneeded = function(event) { |
|
9577 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
9578 |
+ // If this is the case, there will be no call recordings |
|
9579 |
+ } |
|
9580 |
+ request.onsuccess = function(event) { |
|
9581 |
+ console.log("IndexDB connected to CallRecordings"); |
|
9582 |
+ |
|
9583 |
+ var IDB = event.target.result; |
|
9584 |
+ if(IDB.objectStoreNames.contains("Recordings") == false){ |
|
9585 |
+ console.warn("IndexDB CallRecordings.Recordings does not exists"); |
|
9586 |
+ return; |
|
9587 |
+ } |
|
9588 |
+ IDB.onerror = function(event) { |
|
9589 |
+ console.error("IndexDB Error:", event); |
|
9590 |
+ } |
|
9591 |
+ |
|
9592 |
+ // Loop and Delete |
|
9593 |
+ $.each(stream.DataCollection, function (i, item) { |
|
9594 |
+ if (item.Recordings && item.Recordings.length) { |
|
9595 |
+ $.each(item.Recordings, function (i, recording) { |
|
9596 |
+ console.log("Deleting Call Recording: ", recording.uID); |
|
9597 |
+ var objectStore = IDB.transaction(["Recordings"], "readwrite").objectStore("Recordings"); |
|
9598 |
+ try{ |
|
9599 |
+ var deleteRequest = objectStore.delete(recording.uID); |
|
9600 |
+ deleteRequest.onsuccess = function(event) { |
|
9601 |
+ console.log("Call Recording Deleted: ", recording.uID); |
|
9602 |
+ } |
|
9603 |
+ } catch(e){ |
|
9604 |
+ console.log("Call Recording Delete failed: ", e); |
|
9605 |
+ } |
|
9606 |
+ }); |
|
9607 |
+ } |
|
9608 |
+ }); |
|
9609 |
+ } |
|
9610 |
+} |
|
9611 |
+ |
|
9612 |
+function MakeUpName(){ |
|
9613 |
+ var shortname = 4; |
|
9614 |
+ var longName = 12; |
|
9615 |
+ var letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]; |
|
9616 |
+ var rtn = ""; |
|
9617 |
+ rtn += letters[Math.floor(Math.random() * letters.length)]; |
|
9618 |
+ for(var n=0; n<Math.floor(Math.random() * longName) + shortname; n++){ |
|
9619 |
+ rtn += letters[Math.floor(Math.random() * letters.length)].toLowerCase(); |
|
9620 |
+ } |
|
9621 |
+ rtn += " "; |
|
9622 |
+ rtn += letters[Math.floor(Math.random() * letters.length)]; |
|
9623 |
+ for(var n=0; n<Math.floor(Math.random() * longName) + shortname; n++){ |
|
9624 |
+ rtn += letters[Math.floor(Math.random() * letters.length)].toLowerCase(); |
|
9625 |
+ } |
|
9626 |
+ return rtn; |
|
9627 |
+} |
|
9628 |
+function MakeUpNumber(){ |
|
9629 |
+ var numbers = ["0","1","2","3","4","5","6","7","8","9","0"]; |
|
9630 |
+ var rtn = "0"; |
|
9631 |
+ for(var n=0; n<9; n++){ |
|
9632 |
+ rtn += numbers[Math.floor(Math.random() * numbers.length)]; |
|
9633 |
+ } |
|
9634 |
+ return rtn; |
|
9635 |
+} |
|
9636 |
+function MakeUpBuddies(int){ |
|
9637 |
+ for(var i=0; i<int; i++){ |
|
9638 |
+ var buddyObj = new Buddy("contact", uID(), MakeUpName(), "", "", MakeUpNumber(), "", utcDateNow(), "Testing", ""); |
|
9639 |
+ AddBuddy(buddyObj, false, false); |
|
9640 |
+ } |
|
9641 |
+ UpdateBuddyList(); |
|
9642 |
+} |
|
9643 |
+ |
|
9644 |
+function SelectBuddy(buddy) { |
|
9645 |
+ |
|
9646 |
+ $("#roundcubeFrame").remove(); |
|
9647 |
+ $(".streamSelected").each(function() { $(this).show(); }); |
|
9648 |
+ |
|
9649 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
9650 |
+ if(buddyObj == null) return; |
|
9651 |
+ |
|
9652 |
+ for(var b = 0; b < Buddies.length; b++) { |
|
9653 |
+ if(Buddies[b].IsSelected == true && Buddies[b].identity == buddy){ |
|
9654 |
+ // Nothing to do, you re-selected the same buddy; |
|
9655 |
+ return; |
|
9656 |
+ } |
|
9657 |
+ } |
|
9658 |
+ |
|
9659 |
+ console.log("Selecting Buddy: "+ buddy); |
|
9660 |
+ |
|
9661 |
+ selectedBuddy = buddyObj; |
|
9662 |
+ |
|
9663 |
+ // Can only display one thing on the right |
|
9664 |
+ $(".streamSelected").each(function () { |
|
9665 |
+ $(this).prop('class', 'stream'); |
|
9666 |
+ }); |
|
9667 |
+ $("#stream-" + buddy).prop('class', 'streamSelected'); |
|
9668 |
+ |
|
9669 |
+ // Update Lines List |
|
9670 |
+ for(var l = 0; l < Lines.length; l++) { |
|
9671 |
+ var classStr = "buddy"; |
|
9672 |
+ if(Lines[l].SipSession != null) classStr = (Lines[l].SipSession.local_hold)? "buddyActiveCallHollding" : "buddyActiveCall"; |
|
9673 |
+ $("#line-" + Lines[l].LineNumber).prop('class', classStr); |
|
9674 |
+ Lines[l].IsSelected = false; |
|
9675 |
+ } |
|
9676 |
+ |
|
9677 |
+ ClearMissedBadge(buddy); |
|
9678 |
+ // Update Buddy List |
|
9679 |
+ for(var b = 0; b < Buddies.length; b++) { |
|
9680 |
+ var classStr = (Buddies[b].identity == buddy)? "buddySelected" : "buddy"; |
|
9681 |
+ $("#contact-" + Buddies[b].identity).prop('class', classStr); |
|
9682 |
+ |
|
9683 |
+ $("#contact-"+ Buddies[b].identity +"-ChatHistory").empty(); |
|
9684 |
+ |
|
9685 |
+ Buddies[b].IsSelected = (Buddies[b].identity == buddy); |
|
9686 |
+ } |
|
9687 |
+ |
|
9688 |
+ // Change to Stream if in Narrow view |
|
9689 |
+ UpdateUI(); |
|
9690 |
+ |
|
9691 |
+ // Refresh Stream |
|
9692 |
+ RefreshStream(buddyObj); |
|
9693 |
+ |
|
9694 |
+ try{ |
|
9695 |
+ $("#contact-" + buddy).get(0).scrollIntoViewIfNeeded(); |
|
9696 |
+ } catch(e){} |
|
9697 |
+ |
|
9698 |
+ // Save Selected |
|
9699 |
+ localDB.setItem("SelectedBuddy", buddy); |
|
9700 |
+} |
|
9701 |
+function CloseBuddy(buddy){ |
|
9702 |
+ // Lines and Buddies (Left) |
|
9703 |
+ $(".buddySelected").each(function () { |
|
9704 |
+ $(this).prop('class', 'buddy'); |
|
9705 |
+ }); |
|
9706 |
+ // Streams (Right) |
|
9707 |
+ $(".streamSelected").each(function () { |
|
9708 |
+ $(this).prop('class', 'stream'); |
|
9709 |
+ }); |
|
9710 |
+ |
|
9711 |
+ console.log("Closing Buddy: "+ buddy); |
|
9712 |
+ for(var b = 0; b < Buddies.length; b++){ |
|
9713 |
+ Buddies[b].IsSelected = false; |
|
9714 |
+ } |
|
9715 |
+ selectedBuddy = null; |
|
9716 |
+ for(var l = 0; l < Lines.length; l++){ |
|
9717 |
+ Lines[l].IsSelected = false; |
|
9718 |
+ } |
|
9719 |
+ selectedLine = null; |
|
9720 |
+ |
|
9721 |
+ // Save Selected |
|
9722 |
+ localDB.setItem("SelectedBuddy", null); |
|
9723 |
+ |
|
9724 |
+ // Change to Stream if in Narrow view |
|
9725 |
+ UpdateUI(); |
|
9726 |
+} |
|
9727 |
+function DownloadChatText(buddy) { |
|
9728 |
+ |
|
9729 |
+ var buddyInfo = FindBuddyByIdentity(buddy); |
|
9730 |
+ var DispNamePre = buddyInfo.CallerIDName; |
|
9731 |
+ var DispName = DispNamePre.replace(" ", "_"); |
|
9732 |
+ var buddyExt = buddyInfo.ExtNo; |
|
9733 |
+ var presDate = moment().format("YYYY-MM-DD_HH-mm-ss"); |
|
9734 |
+ |
|
9735 |
+ var wholeChatTextTitle = "\n" + "Roundpin Chat With " + DispNamePre + " (extension " + buddyExt + "), saved on " + moment().format("YYYY-MM-DD HH:mm:ss") + "\n\n\n\n"; |
|
9736 |
+ var wholeChatText = ""; |
|
9737 |
+ |
|
9738 |
+ $("#contact-"+buddy+"-ChatHistory .chatMessageTable").each(function() { |
|
9739 |
+ if ($(this).hasClass("theirChatMessage")) { |
|
9740 |
+ wholeChatText += "\n" + DispNamePre + "\n" + $(this).text() + "\n\n"; |
|
9741 |
+ } else { |
|
9742 |
+ wholeChatText += "\n" + "Me" + "\n" + $(this).text() + "\n\n"; |
|
9743 |
+ } |
|
9744 |
+ }); |
|
9745 |
+ |
|
9746 |
+ if (wholeChatText == "") { alert("There is no chat text to save ! "); return; } |
|
9747 |
+ var wholeChatTextConc = wholeChatTextTitle + wholeChatText; |
|
9748 |
+ var downFilename = 'Roundpin_Chat-' + DispName + "_" + presDate; |
|
9749 |
+ var downlink = document.createElement('a'); |
|
9750 |
+ var mimeType = 'text/plain'; |
|
9751 |
+ |
|
9752 |
+ downlink.setAttribute('download', downFilename); |
|
9753 |
+ downlink.setAttribute('href', 'data:' + mimeType + ';charset=utf-8,' + encodeURIComponent(wholeChatTextConc)); |
|
9754 |
+ downlink.click(); |
|
9755 |
+} |
|
9756 |
+function RemoveBuddy(buddy){ |
|
9757 |
+ |
|
9758 |
+ var buddyData = FindBuddyByIdentity(buddy); |
|
9759 |
+ var buddyDisplayName = buddyData.CallerIDName; |
|
9760 |
+ |
|
9761 |
+ // Check if you are on the phone, etc. |
|
9762 |
+ Confirm(lang.confirm_remove_buddy, lang.remove_buddy, function(){ |
|
9763 |
+ for(var b = 0; b < Buddies.length; b++) { |
|
9764 |
+ if(Buddies[b].identity == buddy) { |
|
9765 |
+ RemoveBuddyMessageStream(Buddies[b]); |
|
9766 |
+ UnsubscribeBuddy(Buddies[b]) |
|
9767 |
+ Buddies.splice(b, 1); |
|
9768 |
+ break; |
|
9769 |
+ } |
|
9770 |
+ } |
|
9771 |
+ // Remove contact from SQL database |
|
9772 |
+ deleteBuddyFromSqldb(buddyDisplayName); |
|
9773 |
+ |
|
9774 |
+ UpdateBuddyList(); |
|
9775 |
+ }); |
|
9776 |
+} |
|
9777 |
+function FindBuddyByDid(did){ |
|
9778 |
+ // Used only in Inboud |
|
9779 |
+ for(var b = 0; b < Buddies.length; b++){ |
|
9780 |
+ if(Buddies[b].ExtNo == did || Buddies[b].MobileNumber == did || Buddies[b].ContactNumber1 == did || Buddies[b].ContactNumber2 == did) { |
|
9781 |
+ return Buddies[b]; |
|
9782 |
+ } |
|
9783 |
+ } |
|
9784 |
+ return null; |
|
9785 |
+} |
|
9786 |
+function FindBuddyByExtNo(ExtNo){ |
|
9787 |
+ for(var b = 0; b < Buddies.length; b++){ |
|
9788 |
+ if(Buddies[b].type == "extension" && Buddies[b].ExtNo == ExtNo) return Buddies[b]; |
|
9789 |
+ } |
|
9790 |
+ return null; |
|
9791 |
+} |
|
9792 |
+function FindBuddyByNumber(number){ |
|
9793 |
+ // Number could be: +XXXXXXXXXX |
|
9794 |
+ // Any special characters must be removed prior to adding |
|
9795 |
+ for(var b = 0; b < Buddies.length; b++){ |
|
9796 |
+ if(Buddies[b].MobileNumber == number || Buddies[b].ContactNumber1 == number || Buddies[b].ContactNumber2 == number) { |
|
9797 |
+ return Buddies[b]; |
|
9798 |
+ } |
|
9799 |
+ } |
|
9800 |
+ return null; |
|
9801 |
+} |
|
9802 |
+function FindBuddyByIdentity(identity){ |
|
9803 |
+ for(var b = 0; b < Buddies.length; b++){ |
|
9804 |
+ if(Buddies[b].identity == identity) return Buddies[b]; |
|
9805 |
+ } |
|
9806 |
+ return null; |
|
9807 |
+} |
|
9808 |
+function SearchStream(obj, buddy){ |
|
9809 |
+ var q = obj.value; |
|
9810 |
+ |
|
9811 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
9812 |
+ if(q == ""){ |
|
9813 |
+ console.log("Restore Stream"); |
|
9814 |
+ RefreshStream(buddyObj); |
|
9815 |
+ } |
|
9816 |
+ else{ |
|
9817 |
+ RefreshStream(buddyObj, q); |
|
9818 |
+ } |
|
9819 |
+} |
|
9820 |
+function RefreshStream(buddyObj, filter) { |
|
9821 |
+ $("#contact-" + buddyObj.identity + "-ChatHistory").empty(); |
|
9822 |
+ |
|
9823 |
+ var json = JSON.parse(localDB.getItem(buddyObj.identity +"-stream")); |
|
9824 |
+ if(json == null || json.DataCollection == null) return; |
|
9825 |
+ |
|
9826 |
+ // Sort DataCollection (Newest items first) |
|
9827 |
+ json.DataCollection.sort(function(a, b){ |
|
9828 |
+ var aMo = moment.utc(a.ItemDate.replace(" UTC", "")); |
|
9829 |
+ var bMo = moment.utc(b.ItemDate.replace(" UTC", "")); |
|
9830 |
+ if (aMo.isSameOrAfter(bMo, "second")) { |
|
9831 |
+ return -1; |
|
9832 |
+ } else return 1; |
|
9833 |
+ return 0; |
|
9834 |
+ }); |
|
9835 |
+ |
|
9836 |
+ // Filter |
|
9837 |
+ if(filter && filter != ""){ |
|
9838 |
+ |
|
9839 |
+ console.log("Rows without filter ("+ filter +"): ", json.DataCollection.length); |
|
9840 |
+ json.DataCollection = json.DataCollection.filter(function(item){ |
|
9841 |
+ if(filter.indexOf("date: ") != -1){ |
|
9842 |
+ // Apply Date Filter |
|
9843 |
+ var dateFilter = getFilter(filter, "date"); |
|
9844 |
+ if(dateFilter != "" && item.ItemDate.indexOf(dateFilter) != -1) return true; |
|
9845 |
+ } |
|
9846 |
+ if(item.MessageData && item.MessageData.length > 1){ |
|
9847 |
+ if(item.MessageData.toLowerCase().indexOf(filter.toLowerCase()) != -1) return true; |
|
9848 |
+ if(filter.toLowerCase().indexOf(item.MessageData.toLowerCase()) != -1) return true; |
|
9849 |
+ } |
|
9850 |
+ if (item.ItemType == "MSG") { |
|
9851 |
+ // Special search |
|
9852 |
+ } |
|
9853 |
+ else if (item.ItemType == "CDR") { |
|
9854 |
+ // Tag search |
|
9855 |
+ if(item.Tags && item.Tags.length > 1){ |
|
9856 |
+ var tagFilter = getFilter(filter, "tag"); |
|
9857 |
+ if(tagFilter != "") { |
|
9858 |
+ if(item.Tags.some(function(i){ |
|
9859 |
+ if(tagFilter.toLowerCase().indexOf(i.value.toLowerCase()) != -1) return true; |
|
9860 |
+ if(i.value.toLowerCase().indexOf(tagFilter.toLowerCase()) != -1) return true; |
|
9861 |
+ return false; |
|
9862 |
+ }) == true) return true; |
|
9863 |
+ } |
|
9864 |
+ } |
|
9865 |
+ } |
|
9866 |
+ else if(item.ItemType == "FILE"){ |
|
9867 |
+ |
|
9868 |
+ } |
|
9869 |
+ else if(item.ItemType == "SMS"){ |
|
9870 |
+ // Not yet implemented |
|
9871 |
+ } |
|
9872 |
+ // return true to keep; |
|
9873 |
+ return false; |
|
9874 |
+ }); |
|
9875 |
+ console.log("Rows After Filter: ", json.DataCollection.length); |
|
9876 |
+ } |
|
9877 |
+ |
|
9878 |
+ // Create Buffer |
|
9879 |
+ if(json.DataCollection.length > StreamBuffer){ |
|
9880 |
+ console.log("Rows:", json.DataCollection.length, " (will be trimed to "+ StreamBuffer +")"); |
|
9881 |
+ // Always limit the Stream to {StreamBuffer}, users must search for messages further back |
|
9882 |
+ json.DataCollection.splice(StreamBuffer); |
|
9883 |
+ } |
|
9884 |
+ |
|
9885 |
+ $.each(json.DataCollection, function (i, item) { |
|
9886 |
+ |
|
9887 |
+ var IsToday = moment.utc(item.ItemDate.replace(" UTC", "")).isSame(moment.utc(), "day"); |
|
9888 |
+ var DateTime = " " + moment.utc(item.ItemDate.replace(" UTC", "")).local().calendar(null, { sameElse: DisplayDateFormat }); |
|
9889 |
+ if(IsToday) DateTime = " " + moment.utc(item.ItemDate.replace(" UTC", "")).local().format(DisplayTimeFormat); |
|
9890 |
+ |
|
9891 |
+ if (item.ItemType == "MSG") { |
|
9892 |
+ // Add Chat Message |
|
9893 |
+ // =================== |
|
9894 |
+ var deliveryStatus = "<i class=\"fa fa-question-circle-o SendingMessage\"></i>"; |
|
9895 |
+ if(item.Sent == true) deliveryStatus = "<i class=\"fa fa-check SentMessage\"></i>"; |
|
9896 |
+ if(item.Sent == false) deliveryStatus = "<i class=\"fa fa-exclamation-circle FailedMessage\"></i>"; |
|
9897 |
+ if(item.Delivered) deliveryStatus += "<i class=\"fa fa-check DeliveredMessage\"></i>"; |
|
9898 |
+ |
|
9899 |
+ var formattedMessage = ReformatMessage(item.MessageData); |
|
9900 |
+ var longMessage = (formattedMessage.length > 1000); |
|
9901 |
+ |
|
9902 |
+ if (item.SrcUserId == profileUserID) { |
|
9903 |
+ // You are the source (sending) |
|
9904 |
+ if (formattedMessage.length != 0) { |
|
9905 |
+ var messageString = "<table class=\"ourChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr>"; |
|
9906 |
+ messageString += "<td class=ourChatMessageText onmouseenter=\"ShowChatMenu(this)\" onmouseleave=\"HideChatMenu(this)\">"; |
|
9907 |
+ messageString += "<span onclick=\"ShowMessgeMenu(this,'MSG','"+ item.ItemId +"', '"+ buddyObj.identity +"')\" class=chatMessageDropdown style=\"display:none\"><i class=\"fa fa-chevron-down\"></i></span>"; |
|
9908 |
+ messageString += "<div id=msg-text-"+ item.ItemId +" class=messageText style=\""+ ((longMessage)? "max-height:190px; overflow:hidden" : "") +"\">" + formattedMessage + "</div>"; |
|
9909 |
+ if(longMessage){ |
|
9910 |
+ messageString += "<div id=msg-readmore-"+ item.ItemId +" class=messageReadMore><span onclick=\"ExpandMessage(this,'"+ item.ItemId +"', '"+ buddyObj.identity +"')\">"+ lang.read_more +"</span></div>"; |
|
9911 |
+ } |
|
9912 |
+ |
|
9913 |
+ messageString += "<div class=messageDate>" + DateTime + " " + deliveryStatus +"</div>"; |
|
9914 |
+ messageString += "</td>"; |
|
9915 |
+ messageString += "</tr></table>"; |
|
9916 |
+ } |
|
9917 |
+ } |
|
9918 |
+ else { |
|
9919 |
+ // You are the destination (receiving) |
|
9920 |
+ var ActualSender = ""; |
|
9921 |
+ if (formattedMessage.length != 0) { |
|
9922 |
+ var messageString = "<table class=\"theirChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr>"; |
|
9923 |
+ messageString += "<td class=theirChatMessageText onmouseenter=\"ShowChatMenu(this)\" onmouseleave=\"HideChatMenu(this)\">"; |
|
9924 |
+ messageString += "<span onclick=\"ShowMessgeMenu(this,'MSG','"+ item.ItemId +"', '"+ buddyObj.identity +"')\" class=chatMessageDropdown style=\"display:none\"><i class=\"fa fa-chevron-down\"></i></span>"; |
|
9925 |
+ |
|
9926 |
+ if(buddyObj.type == "group"){ |
|
9927 |
+ messageString += "<div class=messageDate>" + ActualSender + "</div>"; |
|
9928 |
+ } |
|
9929 |
+ messageString += "<div id=msg-text-"+ item.ItemId +" class=messageText style=\""+ ((longMessage)? "max-height:190px; overflow:hidden" : "") +"\">" + formattedMessage + "</div>"; |
|
9930 |
+ if(longMessage){ |
|
9931 |
+ messageString += "<div id=msg-readmore-"+ item.ItemId +" class=messageReadMore><span onclick=\"ExpandMessage(this,'"+ item.ItemId +"', '"+ buddyObj.identity +"')\">"+ lang.read_more +"</span></div>"; |
|
9932 |
+ } |
|
9933 |
+ messageString += "<div class=messageDate>"+ DateTime + "</div>"; |
|
9934 |
+ messageString += "</td>"; |
|
9935 |
+ messageString += "</tr></table>"; |
|
9936 |
+ } |
|
9937 |
+ } |
|
9938 |
+ if (formattedMessage.length != 0) { |
|
9939 |
+ $("#contact-" + buddyObj.identity + "-ChatHistory").prepend(messageString); |
|
9940 |
+ } |
|
9941 |
+ } |
|
9942 |
+ else if (item.ItemType == "CDR") { |
|
9943 |
+ // Add CDR |
|
9944 |
+ // ======= |
|
9945 |
+ var iconColor = (item.Billsec > 0)? "green" : "red"; |
|
9946 |
+ var formattedMessage = ""; |
|
9947 |
+ |
|
9948 |
+ // Flagged |
|
9949 |
+ var flag = "<span id=cdr-flagged-"+ item.CdrId +" style=\""+ ((item.Flagged)? "" : "display:none") +"\">"; |
|
9950 |
+ flag += "<i class=\"fa fa-flag FlagCall\"></i> "; |
|
9951 |
+ flag += "</span>"; |
|
9952 |
+ |
|
9953 |
+ // Comment |
|
9954 |
+ var callComment = ""; |
|
9955 |
+ if(item.MessageData) callComment = item.MessageData; |
|
9956 |
+ |
|
9957 |
+ // Tags |
|
9958 |
+ if(!item.Tags) item.Tags = []; |
|
9959 |
+ var CallTags = "<ul id=cdr-tags-"+ item.CdrId +" class=tags style=\""+ ((item.Tags && item.Tags.length > 0)? "" : "display:none" ) +"\">" |
|
9960 |
+ $.each(item.Tags, function (i, tag) { |
|
9961 |
+ CallTags += "<li onclick=\"TagClick(this, '"+ item.CdrId +"', '"+ buddyObj.identity +"')\">"+ tag.value +"</li>"; |
|
9962 |
+ }); |
|
9963 |
+ CallTags += "<li class=tagText><input maxlength=24 type=text onkeypress=\"TagKeyPress(event, this, '"+ item.CdrId +"', '"+ buddyObj.identity +"')\" onfocus=\"TagFocus(this)\"></li>"; |
|
9964 |
+ CallTags += "</ul>"; |
|
9965 |
+ |
|
9966 |
+ // Call Type |
|
9967 |
+ var callIcon = (item.WithVideo)? "fa-video-camera" : "fa-phone"; |
|
9968 |
+ formattedMessage += "<i class=\"fa "+ callIcon +"\" style=\"color:"+ iconColor +"\"></i>"; |
|
9969 |
+ var audioVideo = (item.WithVideo)? lang.a_video_call : lang.an_audio_call; |
|
9970 |
+ |
|
9971 |
+ // Recordings |
|
9972 |
+ var recordingsHtml = ""; |
|
9973 |
+ if(item.Recordings && item.Recordings.length >= 1){ |
|
9974 |
+ $.each(item.Recordings, function (i, recording) { |
|
9975 |
+ if(recording.uID){ |
|
9976 |
+ var StartTime = moment.utc(recording.startTime.replace(" UTC", "")).local(); |
|
9977 |
+ var StopTime = moment.utc(recording.stopTime.replace(" UTC", "")).local(); |
|
9978 |
+ var recordingDuration = moment.duration(StopTime.diff(StartTime)); |
|
9979 |
+ recordingsHtml += "<div class=callRecording>"; |
|
9980 |
+ if(item.WithVideo){ |
|
9981 |
+ if(recording.Poster){ |
|
9982 |
+ var posterWidth = recording.Poster.width; |
|
9983 |
+ var posterHeight = recording.Poster.height; |
|
9984 |
+ var posterImage = recording.Poster.posterBase64; |
|
9985 |
+ recordingsHtml += "<div><IMG src=\""+ posterImage +"\"><button onclick=\"PlayVideoCallRecording(this, '"+ item.CdrId +"', '"+ recording.uID +"')\" class=videoPoster><i class=\"fa fa-play\"></i></button></div>"; |
|
9986 |
+ } |
|
9987 |
+ else { |
|
9988 |
+ recordingsHtml += "<div><button onclick=\"PlayVideoCallRecording(this, '"+ item.CdrId +"', '"+ recording.uID +"', '"+ buddyObj.identity +"')\"><i class=\"fa fa-video-camera\"></i></button></div>"; |
|
9989 |
+ } |
|
9990 |
+ } |
|
9991 |
+ else { |
|
9992 |
+ recordingsHtml += "<div><button onclick=\"PlayAudioCallRecording(this, '"+ item.CdrId +"', '"+ recording.uID +"', '"+ buddyObj.identity +"')\"><i class=\"fa fa-play\"></i></button></div>"; |
|
9993 |
+ } |
|
9994 |
+ recordingsHtml += "<div>"+ lang.started +": "+ StartTime.format(DisplayTimeFormat) +" <i class=\"fa fa-long-arrow-right\"></i> "+ lang.stopped +": "+ StopTime.format(DisplayTimeFormat) +"</div>"; |
|
9995 |
+ recordingsHtml += "<div>"+ lang.recording_duration +": "+ formatShortDuration(recordingDuration.asSeconds()) +"</div>"; |
|
9996 |
+ recordingsHtml += "<div>"; |
|
9997 |
+ recordingsHtml += "<span id=\"cdr-video-meta-width-"+ item.CdrId +"-"+ recording.uID +"\"></span>"; |
|
9998 |
+ recordingsHtml += "<span id=\"cdr-video-meta-height-"+ item.CdrId +"-"+ recording.uID +"\"></span>"; |
|
9999 |
+ recordingsHtml += "<span id=\"cdr-media-meta-size-"+ item.CdrId +"-"+ recording.uID +"\"></span>"; |
|
10000 |
+ recordingsHtml += "<span id=\"cdr-media-meta-codec-"+ item.CdrId +"-"+ recording.uID +"\"></span>"; |
|
10001 |
+ recordingsHtml += "</div>"; |
|
10002 |
+ recordingsHtml += "</div>"; |
|
10003 |
+ } |
|
10004 |
+ }); |
|
10005 |
+ } |
|
10006 |
+ |
|
10007 |
+ if (item.SrcUserId == profileUserID) { |
|
10008 |
+ // (Outbound) You(profileUserID) initiated a call |
|
10009 |
+ if(item.Billsec == "0") { |
|
10010 |
+ formattedMessage += " "+ lang.you_tried_to_make +" "+ audioVideo +" ("+ item.ReasonText +")."; |
|
10011 |
+ } |
|
10012 |
+ else { |
|
10013 |
+ formattedMessage += " "+ lang.you_made + " "+ audioVideo +", "+ lang.and_spoke_for +" " + formatDuration(item.Billsec) + "."; |
|
10014 |
+ } |
|
10015 |
+ var messageString = "<table class=\"ourChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr>" |
|
10016 |
+ messageString += "<td style=\"padding-right:4px;\">" + flag + "</td>" |
|
10017 |
+ messageString += "<td class=ourChatMessageText onmouseenter=\"ShowChatMenu(this)\" onmouseleave=\"HideChatMenu(this)\">"; |
|
10018 |
+ messageString += "<span onClick=\"ShowMessgeMenu(this,'CDR','"+ item.CdrId +"', '"+ buddyObj.identity +"')\" class=chatMessageDropdown style=\"display:none\"><i class=\"fa fa-chevron-down\"></i></span>"; |
|
10019 |
+ messageString += "<div>" + formattedMessage + "</div>"; |
|
10020 |
+ messageString += "<div>" + CallTags + "</div>"; |
|
10021 |
+ messageString += "<div id=cdr-comment-"+ item.CdrId +" class=cdrComment>" + callComment + "</div>"; |
|
10022 |
+ messageString += "<div class=callRecordings>" + recordingsHtml + "</div>"; |
|
10023 |
+ messageString += "<div class=messageDate>" + DateTime + "</div>"; |
|
10024 |
+ messageString += "</td>" |
|
10025 |
+ messageString += "</tr></table>"; |
|
10026 |
+ } |
|
10027 |
+ else { |
|
10028 |
+ // (Inbound) you(profileUserID) received a call |
|
10029 |
+ if(item.Billsec == "0"){ |
|
10030 |
+ formattedMessage += " "+ lang.you_missed_a_call + " ("+ item.ReasonText +")."; |
|
10031 |
+ } |
|
10032 |
+ else { |
|
10033 |
+ formattedMessage += " "+ lang.you_recieved + " "+ audioVideo +", "+ lang.and_spoke_for +" " + formatDuration(item.Billsec) + "."; |
|
10034 |
+ } |
|
10035 |
+ |
|
10036 |
+ var messageString = "<table class=\"theirChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr>"; |
|
10037 |
+ messageString += "<td class=theirChatMessageText onmouseenter=\"ShowChatMenu(this)\" onmouseleave=\"HideChatMenu(this)\">"; |
|
10038 |
+ messageString += "<span onClick=\"ShowMessgeMenu(this,'CDR','"+ item.CdrId +"', '"+ buddyObj.identity +"')\" class=chatMessageDropdown style=\"display:none\"><i class=\"fa fa-chevron-down\"></i></span>"; |
|
10039 |
+ messageString += "<div style=\"text-align:left\">" + formattedMessage + "</div>"; |
|
10040 |
+ messageString += "<div>" + CallTags + "</div>"; |
|
10041 |
+ messageString += "<div id=cdr-comment-"+ item.CdrId +" class=cdrComment>" + callComment + "</div>"; |
|
10042 |
+ messageString += "<div class=callRecordings>" + recordingsHtml + "</div>"; |
|
10043 |
+ messageString += "<div class=messageDate> " + DateTime + "</div>"; |
|
10044 |
+ messageString += "</td>"; |
|
10045 |
+ messageString += "<td style=\"padding-left:4px\">" + flag + "</td>"; |
|
10046 |
+ messageString += "</tr></table>"; |
|
10047 |
+ } |
|
10048 |
+ // Messges are reappended here, and appended when logging |
|
10049 |
+ $("#contact-" + buddyObj.identity + "-ChatHistory").prepend(messageString); |
|
10050 |
+ } |
|
10051 |
+ else if (item.ItemType == "FILE") { |
|
10052 |
+ |
|
10053 |
+ if (item.SrcUserId == profileUserID) { |
|
10054 |
+ // File is sent |
|
10055 |
+ var sentFileSection = "<table class=\"ourChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr>" |
|
10056 |
+ sentFileSection += "<td><div class='sentFileChatRect'>Download file<br><a href='download-sent-chat-file.php?s_ajax_call="+ validateSToken +"&destSipUser="+ item.Dst +"&sentFlNm="+ item.SentFileName +"' target='_blank'>"+ item.SentFileName +"</a>"; |
|
10057 |
+ sentFileSection += "<span style=\"display:block;width:100%;height:10px;\"></span><div class=\"messageDate\">"+ DateTime + "</div></div>"; |
|
10058 |
+ sentFileSection += "</td>"; |
|
10059 |
+ sentFileSection += "</tr></table>"; |
|
10060 |
+ |
|
10061 |
+ $("#contact-" + buddyObj.identity + "-ChatHistory").prepend(sentFileSection); |
|
10062 |
+ $("#sendFileLoader").remove(); |
|
10063 |
+ |
|
10064 |
+ } else { |
|
10065 |
+ // File is received |
|
10066 |
+ var recFileSection = "<table class=\"theirChatMessage chatMessageTable\" cellspacing=0 cellpadding=0><tr>" |
|
10067 |
+ recFileSection += "<td><div class='recFileChatRect'>Download file<br><a href='download-rec-chat-file.php?s_ajax_call="+ validateSToken +"&recSipUser="+ item.Dst +"&recFlNm="+ item.ReceivedFileName +"' target='_blank'>"+ item.ReceivedFileName +"</a>"; |
|
10068 |
+ |
|
10069 |
+ recFileSection += "<span style=\"display:block;width:100%;height:10px;\"></span><div class=\"messageDate\">"+ DateTime + "</div></div>"; |
|
10070 |
+ recFileSection += "</td>"; |
|
10071 |
+ recFileSection += "</tr></table>"; |
|
10072 |
+ |
|
10073 |
+ $("#contact-" + buddyObj.identity + "-ChatHistory").prepend(recFileSection); |
|
10074 |
+ } |
|
10075 |
+ } |
|
10076 |
+ else if(item.ItemType == "SMS"){ |
|
10077 |
+ |
|
10078 |
+ } |
|
10079 |
+ }); |
|
10080 |
+ |
|
10081 |
+ // For some reason, the first time this fires, it doesn't always work |
|
10082 |
+ updateScroll(buddyObj.identity); |
|
10083 |
+ window.setTimeout(function(){ |
|
10084 |
+ updateScroll(buddyObj.identity); |
|
10085 |
+ }, 300); |
|
10086 |
+} |
|
10087 |
+function ShowChatMenu(obj){ |
|
10088 |
+ $(obj).children("span").show(); |
|
10089 |
+} |
|
10090 |
+function HideChatMenu(obj){ |
|
10091 |
+ $(obj).children("span").hide(); |
|
10092 |
+} |
|
10093 |
+function ExpandMessage(obj, ItemId, buddy){ |
|
10094 |
+ $("#msg-text-" + ItemId).css("max-height", ""); |
|
10095 |
+ $("#msg-text-" + ItemId).css("overflow", ""); |
|
10096 |
+ $("#msg-readmore-" + ItemId).remove(); |
|
10097 |
+ |
|
10098 |
+ $.jeegoopopup.close(); |
|
10099 |
+} |
|
10100 |
+function ShowBuddyDial(obj, buddy){ |
|
10101 |
+ $("#contact-"+ buddy +"-email").show(); |
|
10102 |
+ $("#contact-"+ buddy +"-audio-dial").show(); |
|
10103 |
+ $("#contact-"+ buddy +"-video-dial").show(); |
|
10104 |
+} |
|
10105 |
+function HideBuddyDial(obj, buddy){ |
|
10106 |
+ $("#contact-"+ buddy +"-email").hide(); |
|
10107 |
+ $("#contact-"+ buddy +"-audio-dial").hide(); |
|
10108 |
+ $("#contact-"+ buddy +"-video-dial").hide(); |
|
10109 |
+} |
|
10110 |
+function QuickDialAudio(buddy, obj, event){ |
|
10111 |
+ AudioCallMenu(buddy, obj); |
|
10112 |
+ event.stopPropagation(); |
|
10113 |
+} |
|
10114 |
+function QuickDialVideo(buddy, ExtNo, event){ |
|
10115 |
+ event.stopPropagation(); |
|
10116 |
+ window.setTimeout(function(){ |
|
10117 |
+ DialByLine('video', buddy, ExtNo); |
|
10118 |
+ }, 300); |
|
10119 |
+} |
|
10120 |
+ |
|
10121 |
+// Sessions |
|
10122 |
+// ======== |
|
10123 |
+function ExpandVideoArea(lineNum){ |
|
10124 |
+ $("#line-" + lineNum + "-ActiveCall").prop("class","FullScreenVideo"); |
|
10125 |
+ $("#line-" + lineNum + "-VideoCall").css("height", "calc(100% - 100px)"); |
|
10126 |
+ $("#line-" + lineNum + "-VideoCall").css("margin-top", "0px"); |
|
10127 |
+ |
|
10128 |
+ $("#line-" + lineNum + "-preview-container").prop("class","PreviewContainer PreviewContainer_FS"); |
|
10129 |
+ $("#line-" + lineNum + "-stage-container").prop("class","StageContainer StageContainer_FS"); |
|
10130 |
+ |
|
10131 |
+ $("#line-" + lineNum + "-restore").show(); |
|
10132 |
+ $("#line-" + lineNum + "-expand").hide(); |
|
10133 |
+ |
|
10134 |
+ $("#line-" + lineNum + "-monitoring").hide(); |
|
10135 |
+} |
|
10136 |
+function RestoreVideoArea(lineNum){ |
|
10137 |
+ |
|
10138 |
+ $("#line-" + lineNum + "-ActiveCall").prop("class",""); |
|
10139 |
+ $("#line-" + lineNum + "-VideoCall").css("height", ""); |
|
10140 |
+ $("#line-" + lineNum + "-VideoCall").css("margin-top", "10px"); |
|
10141 |
+ |
|
10142 |
+ $("#line-" + lineNum + "-preview-container").prop("class","PreviewContainer"); |
|
10143 |
+ $("#line-" + lineNum + "-stage-container").prop("class","StageContainer"); |
|
10144 |
+ |
|
10145 |
+ $("#line-" + lineNum + "-restore").hide(); |
|
10146 |
+ $("#line-" + lineNum + "-expand").show(); |
|
10147 |
+ |
|
10148 |
+ $("#line-" + lineNum + "-monitoring").show(); |
|
10149 |
+} |
|
10150 |
+function MuteSession(lineNum){ |
|
10151 |
+ $("#line-"+ lineNum +"-btn-Unmute").show(); |
|
10152 |
+ $("#line-"+ lineNum +"-btn-Mute").hide(); |
|
10153 |
+ |
|
10154 |
+ var lineObj = FindLineByNumber(lineNum); |
|
10155 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
10156 |
+ |
|
10157 |
+ var session = lineObj.SipSession; |
|
10158 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
10159 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
10160 |
+ if(RTCRtpSender.track.kind == "audio") { |
|
10161 |
+ if(RTCRtpSender.track.IsMixedTrack == true){ |
|
10162 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
10163 |
+ console.log("Muting Audio Track : "+ session.data.AudioSourceTrack.label); |
|
10164 |
+ session.data.AudioSourceTrack.enabled = false; |
|
10165 |
+ } |
|
10166 |
+ } |
|
10167 |
+ else { |
|
10168 |
+ console.log("Muting Audio Track : "+ RTCRtpSender.track.label); |
|
10169 |
+ RTCRtpSender.track.enabled = false; |
|
10170 |
+ } |
|
10171 |
+ } |
|
10172 |
+ }); |
|
10173 |
+ |
|
10174 |
+ if(!session.data.mute) session.data.mute = []; |
|
10175 |
+ session.data.mute.push({ event: "mute", eventTime: utcDateNow() }); |
|
10176 |
+ session.data.ismute = true; |
|
10177 |
+ |
|
10178 |
+ $("#line-" + lineNum + "-msg").html(lang.call_on_mute); |
|
10179 |
+ |
|
10180 |
+ updateLineScroll(lineNum); |
|
10181 |
+ |
|
10182 |
+ // Custom Web hook |
|
10183 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("mute", session); |
|
10184 |
+} |
|
10185 |
+function UnmuteSession(lineNum){ |
|
10186 |
+ $("#line-"+ lineNum +"-btn-Unmute").hide(); |
|
10187 |
+ $("#line-"+ lineNum +"-btn-Mute").show(); |
|
10188 |
+ |
|
10189 |
+ var lineObj = FindLineByNumber(lineNum); |
|
10190 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
10191 |
+ |
|
10192 |
+ var session = lineObj.SipSession; |
|
10193 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
10194 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
10195 |
+ if(RTCRtpSender.track.kind == "audio") { |
|
10196 |
+ if(RTCRtpSender.track.IsMixedTrack == true){ |
|
10197 |
+ if(session.data.AudioSourceTrack && session.data.AudioSourceTrack.kind == "audio"){ |
|
10198 |
+ console.log("Unmuting Audio Track : "+ session.data.AudioSourceTrack.label); |
|
10199 |
+ session.data.AudioSourceTrack.enabled = true; |
|
10200 |
+ } |
|
10201 |
+ } |
|
10202 |
+ else { |
|
10203 |
+ console.log("Unmuting Audio Track : "+ RTCRtpSender.track.label); |
|
10204 |
+ RTCRtpSender.track.enabled = true; |
|
10205 |
+ } |
|
10206 |
+ } |
|
10207 |
+ }); |
|
10208 |
+ |
|
10209 |
+ if(!session.data.mute) session.data.mute = []; |
|
10210 |
+ session.data.mute.push({ event: "unmute", eventTime: utcDateNow() }); |
|
10211 |
+ session.data.ismute = false; |
|
10212 |
+ |
|
10213 |
+ $("#line-" + lineNum + "-msg").html(lang.call_off_mute); |
|
10214 |
+ |
|
10215 |
+ updateLineScroll(lineNum); |
|
10216 |
+ |
|
10217 |
+ // Custom Web hook |
|
10218 |
+ if(typeof web_hook_on_modify !== 'undefined') web_hook_on_modify("unmute", session); |
|
10219 |
+} |
|
10220 |
+function ShowDtmfMenu(obj, lineNum){ |
|
10221 |
+ |
|
10222 |
+ var leftPos = event.pageX - 90; |
|
10223 |
+ var topPos = event.pageY + 30; |
|
10224 |
+ |
|
10225 |
+ var html = "<div id=mainDtmfDialPad>"; |
|
10226 |
+ html += "<table cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
10227 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '1');new Audio('sounds/dtmf.mp3').play();\"><div>1</div><span> </span></button></td>" |
|
10228 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '2');new Audio('sounds/dtmf.mp3').play();\"><div>2</div><span>ABC</span></button></td>" |
|
10229 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '3');new Audio('sounds/dtmf.mp3').play();\"><div>3</div><span>DEF</span></button></td></tr>"; |
|
10230 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '4');new Audio('sounds/dtmf.mp3').play();\"><div>4</div><span>GHI</span></button></td>" |
|
10231 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '5');new Audio('sounds/dtmf.mp3').play();\"><div>5</div><span>JKL</span></button></td>" |
|
10232 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '6');new Audio('sounds/dtmf.mp3').play();\"><div>6</div><span>MNO</span></button></td></tr>"; |
|
10233 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '7');new Audio('sounds/dtmf.mp3').play();\"><div>7</div><span>PQRS</span></button></td>" |
|
10234 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '8');new Audio('sounds/dtmf.mp3').play();\"><div>8</div><span>TUV</span></button></td>" |
|
10235 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '9');new Audio('sounds/dtmf.mp3').play();\"><div>9</div><span>WXYZ</span></button></td></tr>"; |
|
10236 |
+ html += "<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '*');new Audio('sounds/dtmf.mp3').play();\">*</button></td>" |
|
10237 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '0');new Audio('sounds/dtmf.mp3').play();\">0</button></td>" |
|
10238 |
+ html += "<td><button class=dtmfButtons onclick=\"sendDTMF('"+ lineNum +"', '#');new Audio('sounds/dtmf.mp3').play();\">#</button></td></tr>"; |
|
10239 |
+ html += "</table>"; |
|
10240 |
+ html += "</div>"; |
|
10241 |
+ |
|
10242 |
+ $.jeegoopopup.open({ |
|
10243 |
+ html: html, |
|
10244 |
+ width: "auto", |
|
10245 |
+ height: "auto", |
|
10246 |
+ left: leftPos, |
|
10247 |
+ top: topPos, |
|
10248 |
+ scrolling: 'no', |
|
10249 |
+ skinClass: 'jg_popup_basic', |
|
10250 |
+ overlay: true, |
|
10251 |
+ opacity: 0, |
|
10252 |
+ draggable: true, |
|
10253 |
+ resizable: false, |
|
10254 |
+ fadeIn: 0 |
|
10255 |
+ }); |
|
10256 |
+ |
|
10257 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
10258 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
10259 |
+} |
|
10260 |
+ |
|
10261 |
+// Stream Functionality |
|
10262 |
+// ===================== |
|
10263 |
+function ShowMessgeMenu(obj, typeStr, cdrId, buddy) { |
|
10264 |
+ |
|
10265 |
+ $.jeegoopopup.close(); |
|
10266 |
+ |
|
10267 |
+ var leftPos = event.pageX; |
|
10268 |
+ var topPos = event.pageY; |
|
10269 |
+ |
|
10270 |
+ if (($(window).width() - event.pageX) < (obj.offsetWidth + 50)) { leftPos = event.pageX - 200; } |
|
10271 |
+ |
|
10272 |
+ var menu = "<div id=\"messageMenu\">"; |
|
10273 |
+ menu += "<table id=\"messageMenuTable\" cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
10274 |
+ |
|
10275 |
+ // CDR's Menu |
|
10276 |
+ if (typeStr == "CDR") { |
|
10277 |
+ var TagState = $("#cdr-flagged-"+ cdrId).is(":visible"); |
|
10278 |
+ var TagText = (TagState)? lang.clear_flag : lang.flag_call; |
|
10279 |
+ menu += "<tr id=\"CMDetails_1\"><td><i class=\"fa fa-external-link\"></i></td><td class=\"callDetails\">"+ lang.show_call_detail_record +"</td></tr>"; |
|
10280 |
+ menu += "<tr id=\"CMDetails_2\"><td><i class=\"fa fa-tags\"></i></td><td class=\"callDetails\">"+ lang.tag_call +"</td></tr>"; |
|
10281 |
+ menu += "<tr id=\"CMDetails_3\"><td><i class=\"fa fa-flag\"></i></td><td class=\"callDetails\">"+ TagText +"</td></tr>"; |
|
10282 |
+ menu += "<tr id=\"CMDetails_4\"><td><i class=\"fa fa-quote-left\"></i></td><td class=\"callDetails\">"+ lang.edit_comment +"</td></tr>"; |
|
10283 |
+ } |
|
10284 |
+ if (typeStr == "MSG") { |
|
10285 |
+ menu += "<tr id=\"CMDetails_5\"><td><i class=\"fa fa-clipboard\"></i></td><td class=\"callDetails\">"+ lang.copy_message +"</td></tr>"; |
|
10286 |
+ menu += "<tr id=\"CMDetails_6\"><td><i class=\"fa fa-quote-left\"></i></td><td class=\"callDetails\">"+ lang.quote_message +"</td></tr>"; |
|
10287 |
+ } |
|
10288 |
+ |
|
10289 |
+ menu += "</table></div>"; |
|
10290 |
+ |
|
10291 |
+ $.jeegoopopup.open({ |
|
10292 |
+ html: menu, |
|
10293 |
+ width: 'auto', |
|
10294 |
+ height: 'auto', |
|
10295 |
+ left: leftPos, |
|
10296 |
+ top: topPos, |
|
10297 |
+ scrolling: 'no', |
|
10298 |
+ skinClass: 'jg_popup_basic', |
|
10299 |
+ overlay: true, |
|
10300 |
+ opacity: 0, |
|
10301 |
+ draggable: false, |
|
10302 |
+ resizable: false, |
|
10303 |
+ fadeIn: 0 |
|
10304 |
+ }); |
|
10305 |
+ |
|
10306 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
10307 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
10308 |
+ |
|
10309 |
+ // CDR messages |
|
10310 |
+ $("#CMDetails_1").click(function(event) { |
|
10311 |
+ |
|
10312 |
+ var cdr = null; |
|
10313 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
10314 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
10315 |
+ $.each(currentStream.DataCollection, function (i, item) { |
|
10316 |
+ if (item.ItemType == "CDR" && item.CdrId == cdrId) { |
|
10317 |
+ // Found |
|
10318 |
+ cdr = item; |
|
10319 |
+ return false; |
|
10320 |
+ } |
|
10321 |
+ }); |
|
10322 |
+ } |
|
10323 |
+ if(cdr == null) return; |
|
10324 |
+ |
|
10325 |
+ var callDetails = []; |
|
10326 |
+ |
|
10327 |
+ var html = '<div id="windowCtrls"><img id="minimizeImg" src="images/1_minimize.svg" title="Restore" /><img id="maximizeImg" src="images/2_maximize.svg" title="Maximize" /><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
10328 |
+ html += "<div class=\"UiWindowField scroller\">"; |
|
10329 |
+ |
|
10330 |
+ var CallDate = moment.utc(cdr.ItemDate.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat); |
|
10331 |
+ var CallAnswer = (cdr.CallAnswer)? moment.utc(cdr.CallAnswer.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat) : null ; |
|
10332 |
+ var ringTime = (cdr.RingTime)? cdr.RingTime : 0 ; |
|
10333 |
+ var CallEnd = moment.utc(cdr.CallEnd.replace(" UTC", "")).local().format(DisplayDateFormat +" "+ DisplayTimeFormat); |
|
10334 |
+ |
|
10335 |
+ var srcCallerID = ""; |
|
10336 |
+ var dstCallerID = ""; |
|
10337 |
+ if(cdr.CallDirection == "inbound") { |
|
10338 |
+ srcCallerID = cdr.Src; |
|
10339 |
+ } |
|
10340 |
+ else if(cdr.CallDirection == "outbound") { |
|
10341 |
+ dstCallerID = cdr.Dst; |
|
10342 |
+ } |
|
10343 |
+ html += "<div class=UiText><b>SIP CallID</b> : "+ cdr.SessionId +"</div>"; |
|
10344 |
+ html += "<div class=UiText><b>"+ lang.call_direction +"</b> : "+ cdr.CallDirection +"</div>"; |
|
10345 |
+ html += "<div class=UiText><b>"+ lang.call_date_and_time +"</b> : "+ CallDate +"</div>"; |
|
10346 |
+ html += "<div class=UiText><b>"+ lang.ring_time +"</b> : "+ formatDuration(ringTime) +" ("+ ringTime +")</div>"; |
|
10347 |
+ html += "<div class=UiText><b>"+ lang.talk_time +"</b> : " + formatDuration(cdr.Billsec) +" ("+ cdr.Billsec +")</div>"; |
|
10348 |
+ html += "<div class=UiText><b>"+ lang.call_duration +"</b> : "+ formatDuration(cdr.TotalDuration) +" ("+ cdr.TotalDuration +")</div>"; |
|
10349 |
+ html += "<div class=UiText><b>"+ lang.video_call +"</b> : "+ ((cdr.WithVideo)? lang.yes : lang.no) +"</div>"; |
|
10350 |
+ html += "<div class=UiText><b>"+ lang.flagged +"</b> : "+ ((cdr.Flagged)? "<i class=\"fa fa-flag FlagCall\"></i> " + lang.yes : lang.no) +"</div>"; |
|
10351 |
+ html += "<hr>"; |
|
10352 |
+ html += "<h2 style=\"font-size: 16px\">"+ lang.call_tags +"</h2>"; |
|
10353 |
+ html += "<hr>"; |
|
10354 |
+ $.each(cdr.Tags, function(item, tag){ |
|
10355 |
+ html += "<span class=cdrTag>"+ tag.value +"</span>" |
|
10356 |
+ }); |
|
10357 |
+ |
|
10358 |
+ html += "<h2 style=\"font-size: 16px\">"+ lang.call_notes +"</h2>"; |
|
10359 |
+ html += "<hr>"; |
|
10360 |
+ if(cdr.MessageData){ |
|
10361 |
+ html += "\"" + cdr.MessageData + "\""; |
|
10362 |
+ } |
|
10363 |
+ |
|
10364 |
+ html += "<h2 style=\"font-size: 16px\">"+ lang.activity_timeline +"</h2>"; |
|
10365 |
+ html += "<hr>"; |
|
10366 |
+ |
|
10367 |
+ var withVideo = (cdr.WithVideo)? "("+ lang.with_video +")" : ""; |
|
10368 |
+ var startCallMessage = (cdr.CallDirection == "inbound")? lang.you_received_a_call_from + " " + srcCallerID +" "+ withVideo : lang.you_made_a_call_to + " " + dstCallerID +" "+ withVideo; |
|
10369 |
+ callDetails.push({ |
|
10370 |
+ Message: startCallMessage, |
|
10371 |
+ TimeStr: cdr.ItemDate |
|
10372 |
+ }); |
|
10373 |
+ if(CallAnswer){ |
|
10374 |
+ var answerCallMessage = (cdr.CallDirection == "inbound")? lang.you_answered_after + " " + ringTime + " " + lang.seconds_plural : lang.they_answered_after + " " + ringTime + " " + lang.seconds_plural; |
|
10375 |
+ callDetails.push({ |
|
10376 |
+ Message: answerCallMessage, |
|
10377 |
+ TimeStr: cdr.CallAnswer |
|
10378 |
+ }); |
|
10379 |
+ } |
|
10380 |
+ $.each(cdr.Transfers, function(item, transfer){ |
|
10381 |
+ var msg = (transfer.type == "Blind")? lang.you_started_a_blind_transfer_to +" "+ transfer.to +". " : lang.you_started_an_attended_transfer_to + " "+ transfer.to +". "; |
|
10382 |
+ if(transfer.accept && transfer.accept.complete == true){ |
|
10383 |
+ msg += lang.the_call_was_completed |
|
10384 |
+ } |
|
10385 |
+ else if(transfer.accept.disposition != "") { |
|
10386 |
+ msg += lang.the_call_was_not_completed +" ("+ transfer.accept.disposition +")" |
|
10387 |
+ } |
|
10388 |
+ callDetails.push({ |
|
10389 |
+ Message : msg, |
|
10390 |
+ TimeStr : transfer.transferTime |
|
10391 |
+ }); |
|
10392 |
+ }); |
|
10393 |
+ $.each(cdr.Mutes, function(item, mute){ |
|
10394 |
+ callDetails.push({ |
|
10395 |
+ Message : (mute.event == "mute")? lang.you_put_the_call_on_mute : lang.you_took_the_call_off_mute, |
|
10396 |
+ TimeStr : mute.eventTime |
|
10397 |
+ }); |
|
10398 |
+ }); |
|
10399 |
+ $.each(cdr.Holds, function(item, hold){ |
|
10400 |
+ callDetails.push({ |
|
10401 |
+ Message : (hold.event == "hold")? lang.you_put_the_call_on_hold : lang.you_took_the_call_off_hold, |
|
10402 |
+ TimeStr : hold.eventTime |
|
10403 |
+ }); |
|
10404 |
+ }); |
|
10405 |
+ $.each(cdr.ConfCalls, function(item, confCall){ |
|
10406 |
+ var msg = lang.you_started_a_conference_call_to +" "+ confCall.to +". "; |
|
10407 |
+ if(confCall.accept && confCall.accept.complete == true){ |
|
10408 |
+ msg += lang.the_call_was_completed |
|
10409 |
+ } |
|
10410 |
+ else if(confCall.accept.disposition != "") { |
|
10411 |
+ msg += lang.the_call_was_not_completed +" ("+ confCall.accept.disposition +")" |
|
10412 |
+ } |
|
10413 |
+ callDetails.push({ |
|
10414 |
+ Message : msg, |
|
10415 |
+ TimeStr : confCall.startTime |
|
10416 |
+ }); |
|
10417 |
+ }); |
|
10418 |
+ $.each(cdr.Recordings, function(item, recording){ |
|
10419 |
+ var StartTime = moment.utc(recording.startTime.replace(" UTC", "")).local(); |
|
10420 |
+ var StopTime = moment.utc(recording.stopTime.replace(" UTC", "")).local(); |
|
10421 |
+ var recordingDuration = moment.duration(StopTime.diff(StartTime)); |
|
10422 |
+ |
|
10423 |
+ var msg = lang.call_is_being_recorded; |
|
10424 |
+ if(recording.startTime != recording.stopTime){ |
|
10425 |
+ msg += "("+ formatShortDuration(recordingDuration.asSeconds()) +")" |
|
10426 |
+ } |
|
10427 |
+ callDetails.push({ |
|
10428 |
+ Message : msg, |
|
10429 |
+ TimeStr : recording.startTime |
|
10430 |
+ }); |
|
10431 |
+ }); |
|
10432 |
+ callDetails.push({ |
|
10433 |
+ Message: (cdr.Terminate == "us")? "You ended the call." : "They ended the call", |
|
10434 |
+ TimeStr : cdr.CallEnd |
|
10435 |
+ }); |
|
10436 |
+ |
|
10437 |
+ callDetails.sort(function(a, b){ |
|
10438 |
+ var aMo = moment.utc(a.TimeStr.replace(" UTC", "")); |
|
10439 |
+ var bMo = moment.utc(b.TimeStr.replace(" UTC", "")); |
|
10440 |
+ if (aMo.isSameOrAfter(bMo, "second")) { |
|
10441 |
+ return 1; |
|
10442 |
+ } else return -1; |
|
10443 |
+ return 0; |
|
10444 |
+ }); |
|
10445 |
+ $.each(callDetails, function(item, detail){ |
|
10446 |
+ var Time = moment.utc(detail.TimeStr.replace(" UTC", "")).local().format(DisplayTimeFormat); |
|
10447 |
+ var messageString = "<table class=timelineMessage cellspacing=0 cellpadding=0><tr>" |
|
10448 |
+ messageString += "<td class=timelineMessageArea>" |
|
10449 |
+ messageString += "<div class=timelineMessageDate style=\"color: #333333\"><i class=\"fa fa-circle timelineMessageDot\"></i>"+ Time +"</div>" |
|
10450 |
+ messageString += "<div class=timelineMessageText style=\"color: #000000\">"+ detail.Message +"</div>" |
|
10451 |
+ messageString += "</td>" |
|
10452 |
+ messageString += "</tr></table>"; |
|
10453 |
+ html += messageString; |
|
10454 |
+ }); |
|
10455 |
+ |
|
10456 |
+ html += "<h2 style=\"font-size: 16px\">"+ lang.call_recordings +"</h2>"; |
|
10457 |
+ html += "<hr>"; |
|
10458 |
+ var recordingsHtml = ""; |
|
10459 |
+ $.each(cdr.Recordings, function(r, recording){ |
|
10460 |
+ if(recording.uID){ |
|
10461 |
+ var StartTime = moment.utc(recording.startTime.replace(" UTC", "")).local(); |
|
10462 |
+ var StopTime = moment.utc(recording.stopTime.replace(" UTC", "")).local(); |
|
10463 |
+ var recordingDuration = moment.duration(StopTime.diff(StartTime)); |
|
10464 |
+ recordingsHtml += "<div>"; |
|
10465 |
+ if(cdr.WithVideo){ |
|
10466 |
+ recordingsHtml += "<div><video id=\"callrecording-video-"+ recording.uID +"\" controls style=\"width: 100%\"></div>"; |
|
10467 |
+ } |
|
10468 |
+ else { |
|
10469 |
+ recordingsHtml += "<div><audio id=\"callrecording-audio-"+ recording.uID +"\" controls style=\"width: 100%\"></div>"; |
|
10470 |
+ } |
|
10471 |
+ recordingsHtml += "<div>"+ lang.started +": "+ StartTime.format(DisplayTimeFormat) +" <i class=\"fa fa-long-arrow-right\"></i> "+ lang.stopped +": "+ StopTime.format(DisplayTimeFormat) +"</div>"; |
|
10472 |
+ recordingsHtml += "<div>"+ lang.recording_duration +": "+ formatShortDuration(recordingDuration.asSeconds()) +"</div>"; |
|
10473 |
+ recordingsHtml += "<div><a id=\"download-"+ recording.uID +"\">"+ lang.save_as +"</a> ("+ lang.right_click_and_select_save_link_as +")</div>"; |
|
10474 |
+ recordingsHtml += "</div>"; |
|
10475 |
+ } |
|
10476 |
+ }); |
|
10477 |
+ html += recordingsHtml; |
|
10478 |
+ |
|
10479 |
+ html += "<h2 style=\"font-size: 16px\">"+ lang.send_statistics +"</h2>"; |
|
10480 |
+ html += "<hr>"; |
|
10481 |
+ |
|
10482 |
+ html += "<div style=\"position: relative; margin: auto; height: 160px; width: 100%;\"><canvas id=\"cdr-AudioSendBitRate\"></canvas></div>"; |
|
10483 |
+ html += "<div style=\"position: relative; margin: auto; height: 160px; width: 100%;\"><canvas id=\"cdr-AudioSendPacketRate\"></canvas></div>"; |
|
10484 |
+ |
|
10485 |
+ html += "<h2 style=\"font-size: 16px\">"+ lang.receive_statistics +"</h2>"; |
|
10486 |
+ html += "<hr>"; |
|
10487 |
+ |
|
10488 |
+ html += "<div style=\"position: relative; margin: auto; height: 160px; width: 100%;\"><canvas id=\"cdr-AudioReceiveBitRate\"></canvas></div>"; |
|
10489 |
+ html += "<div style=\"position: relative; margin: auto; height: 160px; width: 100%;\"><canvas id=\"cdr-AudioReceivePacketRate\"></canvas></div>"; |
|
10490 |
+ html += "<div style=\"position: relative; margin: auto; height: 160px; width: 100%;\"><canvas id=\"cdr-AudioReceivePacketLoss\"></canvas></div>"; |
|
10491 |
+ html += "<div style=\"position: relative; margin: auto; height: 160px; width: 100%;\"><canvas id=\"cdr-AudioReceiveJitter\"></canvas></div>"; |
|
10492 |
+ html += "<div style=\"position: relative; margin: auto; height: 160px; width: 100%;\"><canvas id=\"cdr-AudioReceiveLevels\"></canvas></div>"; |
|
10493 |
+ |
|
10494 |
+ html += "<br><br></div>"; |
|
10495 |
+ |
|
10496 |
+ $.jeegoopopup.close(); |
|
10497 |
+ |
|
10498 |
+ $.jeegoopopup.open({ |
|
10499 |
+ title: 'Call Statistics', |
|
10500 |
+ html: html, |
|
10501 |
+ width: '640', |
|
10502 |
+ height: '500', |
|
10503 |
+ center: true, |
|
10504 |
+ scrolling: 'no', |
|
10505 |
+ skinClass: 'jg_popup_basic', |
|
10506 |
+ overlay: true, |
|
10507 |
+ opacity: 50, |
|
10508 |
+ draggable: true, |
|
10509 |
+ resizable: false, |
|
10510 |
+ fadeIn: 0 |
|
10511 |
+ }); |
|
10512 |
+ |
|
10513 |
+ $("#jg_popup_b").append('<button id="ok_button">'+ lang.ok +'</button>'); |
|
10514 |
+ |
|
10515 |
+ // Display QOS data |
|
10516 |
+ DisplayQosData(cdr.SessionId); |
|
10517 |
+ |
|
10518 |
+ |
|
10519 |
+ var maxWidth = $(window).width() - 12; |
|
10520 |
+ var maxHeight = $(window).height() - 88; |
|
10521 |
+ |
|
10522 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
10523 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
10524 |
+ $.jeegoopopup.center(); |
|
10525 |
+ $("#maximizeImg").hide(); |
|
10526 |
+ $("#minimizeImg").hide(); |
|
10527 |
+ } else { |
|
10528 |
+ $.jeegoopopup.width(640).height(500); |
|
10529 |
+ $.jeegoopopup.center(); |
|
10530 |
+ $("#minimizeImg").hide(); |
|
10531 |
+ $("#maximizeImg").show(); |
|
10532 |
+ } |
|
10533 |
+ |
|
10534 |
+ $(window).resize(function() { |
|
10535 |
+ maxWidth = $(window).width() - 12; |
|
10536 |
+ maxHeight = $(window).height() - 88; |
|
10537 |
+ $.jeegoopopup.center(); |
|
10538 |
+ if (maxWidth < 656 || maxHeight < 500) { |
|
10539 |
+ $.jeegoopopup.width(maxWidth).height(maxHeight); |
|
10540 |
+ $.jeegoopopup.center(); |
|
10541 |
+ $("#maximizeImg").hide(); |
|
10542 |
+ $("#minimizeImg").hide(); |
|
10543 |
+ } else { |
|
10544 |
+ $.jeegoopopup.width(640).height(500); |
|
10545 |
+ $.jeegoopopup.center(); |
|
10546 |
+ $("#minimizeImg").hide(); |
|
10547 |
+ $("#maximizeImg").show(); |
|
10548 |
+ } |
|
10549 |
+ }); |
|
10550 |
+ |
|
10551 |
+ |
|
10552 |
+ $("#minimizeImg").click(function() { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); }); |
|
10553 |
+ $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); }); |
|
10554 |
+ |
|
10555 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
10556 |
+ $("#ok_button").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
10557 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
10558 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); |
|
10559 |
+ |
|
10560 |
+ |
|
10561 |
+ // Queue video and audio |
|
10562 |
+ $.each(cdr.Recordings, function(r, recording){ |
|
10563 |
+ var mediaObj = null; |
|
10564 |
+ if(cdr.WithVideo){ |
|
10565 |
+ mediaObj = $("#callrecording-video-"+ recording.uID).get(0); |
|
10566 |
+ } |
|
10567 |
+ else { |
|
10568 |
+ mediaObj = $("#callrecording-audio-"+ recording.uID).get(0); |
|
10569 |
+ } |
|
10570 |
+ var downloadURL = $("#download-"+ recording.uID); |
|
10571 |
+ |
|
10572 |
+ // Playback device |
|
10573 |
+ var sinkId = getAudioOutputID(); |
|
10574 |
+ if (typeof mediaObj.sinkId !== 'undefined') { |
|
10575 |
+ mediaObj.setSinkId(sinkId).then(function(){ |
|
10576 |
+ console.log("sinkId applied: "+ sinkId); |
|
10577 |
+ }).catch(function(e){ |
|
10578 |
+ console.warn("Error using setSinkId: ", e); |
|
10579 |
+ }); |
|
10580 |
+ } else { |
|
10581 |
+ console.warn("setSinkId() is not possible using this browser.") |
|
10582 |
+ } |
|
10583 |
+ |
|
10584 |
+ // Get Call Recording |
|
10585 |
+ var indexedDB = window.indexedDB; |
|
10586 |
+ var request = indexedDB.open("CallRecordings"); |
|
10587 |
+ request.onerror = function(event) { |
|
10588 |
+ console.error("IndexDB Request Error:", event); |
|
10589 |
+ } |
|
10590 |
+ request.onupgradeneeded = function(event) { |
|
10591 |
+ console.warn("Upgrade Required for IndexDB... probably because of first time use."); |
|
10592 |
+ } |
|
10593 |
+ request.onsuccess = function(event) { |
|
10594 |
+ console.log("IndexDB connected to CallRecordings"); |
|
10595 |
+ |
|
10596 |
+ var IDB = event.target.result; |
|
10597 |
+ if(IDB.objectStoreNames.contains("Recordings") == false){ |
|
10598 |
+ console.warn("IndexDB CallRecordings.Recordings does not exists"); |
|
10599 |
+ return; |
|
10600 |
+ } |
|
10601 |
+ |
|
10602 |
+ var transaction = IDB.transaction(["Recordings"]); |
|
10603 |
+ var objectStoreGet = transaction.objectStore("Recordings").get(recording.uID); |
|
10604 |
+ objectStoreGet.onerror = function(event) { |
|
10605 |
+ console.error("IndexDB Get Error:", event); |
|
10606 |
+ } |
|
10607 |
+ objectStoreGet.onsuccess = function(event) { |
|
10608 |
+ var mediaBlobUrl = window.URL.createObjectURL(event.target.result.mediaBlob); |
|
10609 |
+ mediaObj.src = mediaBlobUrl; |
|
10610 |
+ |
|
10611 |
+ // Download Link |
|
10612 |
+ if(cdr.WithVideo){ |
|
10613 |
+ downloadURL.prop("download", "Video-Call-Recording-"+ recording.uID +".webm"); |
|
10614 |
+ } |
|
10615 |
+ else { |
|
10616 |
+ downloadURL.prop("download", "Audio-Call-Recording-"+ recording.uID +".webm"); |
|
10617 |
+ } |
|
10618 |
+ downloadURL.prop("href", mediaBlobUrl); |
|
10619 |
+ } |
|
10620 |
+ } |
|
10621 |
+ |
|
10622 |
+ }); |
|
10623 |
+ |
|
10624 |
+ }); |
|
10625 |
+ |
|
10626 |
+ $("#CMDetails_2").click(function(event) { |
|
10627 |
+ $("#cdr-tags-"+ cdrId).show(); |
|
10628 |
+ |
|
10629 |
+ $.jeegoopopup.close(); |
|
10630 |
+ }); |
|
10631 |
+ |
|
10632 |
+ $("#CMDetails_3").click(function(event) { |
|
10633 |
+ // Tag / Untag Call |
|
10634 |
+ var TagState = $("#cdr-flagged-"+ cdrId).is(":visible"); |
|
10635 |
+ if(TagState){ |
|
10636 |
+ console.log("Clearing Flag from: ", cdrId); |
|
10637 |
+ $("#cdr-flagged-"+ cdrId).hide(); |
|
10638 |
+ |
|
10639 |
+ // Update DB |
|
10640 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
10641 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
10642 |
+ $.each(currentStream.DataCollection, function (i, item) { |
|
10643 |
+ if (item.ItemType == "CDR" && item.CdrId == cdrId) { |
|
10644 |
+ // Found |
|
10645 |
+ item.Flagged = false; |
|
10646 |
+ return false; |
|
10647 |
+ } |
|
10648 |
+ }); |
|
10649 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
10650 |
+ } |
|
10651 |
+ } |
|
10652 |
+ else { |
|
10653 |
+ console.log("Flag Call: ", cdrId); |
|
10654 |
+ $("#cdr-flagged-"+ cdrId).show(); |
|
10655 |
+ |
|
10656 |
+ // Update DB |
|
10657 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
10658 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
10659 |
+ $.each(currentStream.DataCollection, function (i, item) { |
|
10660 |
+ if (item.ItemType == "CDR" && item.CdrId == cdrId) { |
|
10661 |
+ // Found |
|
10662 |
+ item.Flagged = true; |
|
10663 |
+ return false; |
|
10664 |
+ } |
|
10665 |
+ }); |
|
10666 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
10667 |
+ } |
|
10668 |
+ } |
|
10669 |
+ |
|
10670 |
+ $.jeegoopopup.close(); |
|
10671 |
+ }); |
|
10672 |
+ |
|
10673 |
+ $("#CMDetails_4").click(function(event) { |
|
10674 |
+ |
|
10675 |
+ var currentText = $("#cdr-comment-"+ cdrId).text(); |
|
10676 |
+ $("#cdr-comment-"+ cdrId).empty(); |
|
10677 |
+ |
|
10678 |
+ var textboxObj = $("<input maxlength=500 type=text>").appendTo("#cdr-comment-"+ cdrId); |
|
10679 |
+ textboxObj.on("focus", function(){ |
|
10680 |
+ $.jeegoopopup.close(); |
|
10681 |
+ }); |
|
10682 |
+ textboxObj.on("blur", function(){ |
|
10683 |
+ var newText = $(this).val(); |
|
10684 |
+ SaveComment(cdrId, buddy, newText); |
|
10685 |
+ }); |
|
10686 |
+ textboxObj.keypress(function(event){ |
|
10687 |
+ window.setTimeout(function(){ |
|
10688 |
+ |
|
10689 |
+ $.jeegoopopup.close(); |
|
10690 |
+ |
|
10691 |
+ }, 500); |
|
10692 |
+ |
|
10693 |
+ var keycode = (event.keyCode ? event.keyCode : event.which); |
|
10694 |
+ if (keycode == '13') { |
|
10695 |
+ event.preventDefault(); |
|
10696 |
+ |
|
10697 |
+ var newText = $(this).val(); |
|
10698 |
+ SaveComment(cdrId, buddy, newText); |
|
10699 |
+ } |
|
10700 |
+ }); |
|
10701 |
+ textboxObj.val(currentText); |
|
10702 |
+ textboxObj.focus(); |
|
10703 |
+ |
|
10704 |
+ $.jeegoopopup.close(); |
|
10705 |
+ }); |
|
10706 |
+ |
|
10707 |
+ $("#CMDetails_5").click(function(event) { |
|
10708 |
+ // Text Messages |
|
10709 |
+ var msgtext = $("#msg-text-"+ cdrId).text(); |
|
10710 |
+ navigator.clipboard.writeText(msgtext).then(function(){ |
|
10711 |
+ console.log("Text coppied to the clipboard:", msgtext); |
|
10712 |
+ }).catch(function(){ |
|
10713 |
+ console.error("Error writing to the clipboard:", e); |
|
10714 |
+ }); |
|
10715 |
+ |
|
10716 |
+ $.jeegoopopup.close(); |
|
10717 |
+ }); |
|
10718 |
+ |
|
10719 |
+ $("#CMDetails_6").click(function(event) { |
|
10720 |
+ |
|
10721 |
+ var msgtext = $("#msg-text-"+ cdrId).text(); |
|
10722 |
+ msgtext = "\""+ msgtext + "\""; |
|
10723 |
+ var textarea = $("#contact-"+ buddy +"-ChatMessage"); |
|
10724 |
+ console.log("Quote Message:", msgtext); |
|
10725 |
+ textarea.val(msgtext +"\n" + textarea.val()); |
|
10726 |
+ |
|
10727 |
+ $.jeegoopopup.close(); |
|
10728 |
+ }); |
|
10729 |
+ |
|
10730 |
+} |
|
10731 |
+function SaveComment(cdrId, buddy, newText){ |
|
10732 |
+ console.log("Setting Comment:", newText); |
|
10733 |
+ |
|
10734 |
+ $("#cdr-comment-"+ cdrId).empty(); |
|
10735 |
+ $("#cdr-comment-"+ cdrId).append(newText); |
|
10736 |
+ |
|
10737 |
+ // Update DB |
|
10738 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
10739 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
10740 |
+ $.each(currentStream.DataCollection, function (i, item) { |
|
10741 |
+ if (item.ItemType == "CDR" && item.CdrId == cdrId) { |
|
10742 |
+ // Found |
|
10743 |
+ item.MessageData = newText; |
|
10744 |
+ return false; |
|
10745 |
+ } |
|
10746 |
+ }); |
|
10747 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
10748 |
+ } |
|
10749 |
+} |
|
10750 |
+function TagKeyPress(event, obj, cdrId, buddy){ |
|
10751 |
+ |
|
10752 |
+ $.jeegoopopup.close(); |
|
10753 |
+ |
|
10754 |
+ var keycode = (event.keyCode ? event.keyCode : event.which); |
|
10755 |
+ if (keycode == '13' || keycode == '44') { |
|
10756 |
+ event.preventDefault(); |
|
10757 |
+ |
|
10758 |
+ if ($(obj).val() == "") return; |
|
10759 |
+ |
|
10760 |
+ console.log("Adding Tag:", $(obj).val()); |
|
10761 |
+ |
|
10762 |
+ $("#cdr-tags-"+ cdrId+" li:last").before("<li onclick=\"TagClick(this, '"+ cdrId +"', '"+ buddy +"')\">"+ $(obj).val() +"</li>"); |
|
10763 |
+ $(obj).val(""); |
|
10764 |
+ |
|
10765 |
+ // Update DB |
|
10766 |
+ UpdateTags(cdrId, buddy); |
|
10767 |
+ } |
|
10768 |
+} |
|
10769 |
+function TagClick(obj, cdrId, buddy){ |
|
10770 |
+ window.setTimeout(function(){ |
|
10771 |
+ $.jeegoopopup.close(); |
|
10772 |
+ }, 500); |
|
10773 |
+ |
|
10774 |
+ console.log("Removing Tag:", $(obj).text()); |
|
10775 |
+ $(obj).remove(); |
|
10776 |
+ |
|
10777 |
+ // Dpdate DB |
|
10778 |
+ UpdateTags(cdrId, buddy); |
|
10779 |
+} |
|
10780 |
+function UpdateTags(cdrId, buddy){ |
|
10781 |
+ var currentStream = JSON.parse(localDB.getItem(buddy + "-stream")); |
|
10782 |
+ if(currentStream != null || currentStream.DataCollection != null){ |
|
10783 |
+ $.each(currentStream.DataCollection, function (i, item) { |
|
10784 |
+ if (item.ItemType == "CDR" && item.CdrId == cdrId) { |
|
10785 |
+ // Found |
|
10786 |
+ item.Tags = []; |
|
10787 |
+ $("#cdr-tags-"+ cdrId).children('li').each(function () { |
|
10788 |
+ if($(this).prop("class") != "tagText") item.Tags.push({ value: $(this).text() }); |
|
10789 |
+ }); |
|
10790 |
+ return false; |
|
10791 |
+ } |
|
10792 |
+ }); |
|
10793 |
+ localDB.setItem(buddy + "-stream", JSON.stringify(currentStream)); |
|
10794 |
+ } |
|
10795 |
+} |
|
10796 |
+ |
|
10797 |
+function TagFocus(obj){ |
|
10798 |
+ $.jeegoopopup.close(); |
|
10799 |
+} |
|
10800 |
+function SendFile(buddy) { |
|
10801 |
+ |
|
10802 |
+ $('#selectedFile').val(''); |
|
10803 |
+ $("#upFile").empty(); |
|
10804 |
+ |
|
10805 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
10806 |
+ var uploadfile = '<form id="sendFileFormChat" enctype="multipart/form-data">'; |
|
10807 |
+ uploadfile += '<input type="hidden" name="MAX_FILE_SIZE" value="786432000" />'; |
|
10808 |
+ uploadfile += '<input type="hidden" name="sipUser" value="'+ buddyObj.ExtNo +'" />'; |
|
10809 |
+ uploadfile += '<input type="hidden" name="s_ajax_call" value="'+ validateSToken +'" />'; |
|
10810 |
+ uploadfile += '<label for="selectedFile" class="customBrowseButton">Select File</label>'; |
|
10811 |
+ uploadfile += '<span id="upFile"></span>'; |
|
10812 |
+ uploadfile += '<input type="file" id="selectedFile" name="uploadedFile" />'; |
|
10813 |
+ uploadfile += '<input type="submit" id="submitFileChat" value="Send File" style="visibility:hidden;"/>'; |
|
10814 |
+ uploadfile += '</form>'; |
|
10815 |
+ |
|
10816 |
+ if ($("#sendFileFormChat").is(":visible")) { |
|
10817 |
+ $("#sendFileFormChat").remove(); |
|
10818 |
+ sendFileCheck = 0; |
|
10819 |
+ } else { |
|
10820 |
+ sendFileCheck = 1; |
|
10821 |
+ $("#contact-"+ buddy +"-ChatMessage").before(uploadfile); |
|
10822 |
+ $("#sendFileFormChat").css("display", "block"); |
|
10823 |
+ |
|
10824 |
+ $("#selectedFile").bind("change", function() { |
|
10825 |
+ upFileName = $(this).val().split('\\').pop(); |
|
10826 |
+ if (/^[a-zA-Z0-9\-\_\.]+$/.test(upFileName)) { |
|
10827 |
+ $("#upFile").html(upFileName); |
|
10828 |
+ } else { |
|
10829 |
+ $("#sendFileFormChat").remove(); |
|
10830 |
+ sendFileCheck = 0; |
|
10831 |
+ alert("The name of the uploaded file is not valid!"); |
|
10832 |
+ } |
|
10833 |
+ }); |
|
10834 |
+ } |
|
10835 |
+} |
|
10836 |
+ |
|
10837 |
+function ShowEmojiBar(buddy) { |
|
10838 |
+ |
|
10839 |
+ var messageContainer = $("#contact-"+ buddy +"-emoji-menu"); |
|
10840 |
+ var textarea = $("#contact-"+ buddy +"-ChatMessage"); |
|
10841 |
+ |
|
10842 |
+ if (messageContainer.is(":visible")) { messageContainer.hide(); } else { messageContainer.show(); } |
|
10843 |
+ |
|
10844 |
+ var menuBar = $("<div>"); |
|
10845 |
+ menuBar.prop("class", "emojiButton") |
|
10846 |
+ var emojis = ["😀","😁","😂","😃","😄","😅","😆","😊","😦","😉","😊","😋","😌","😍","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😛","😜","😝","😞","😟","😠","😡","😢","😣","😤","😥","😦","😧","😨","😩","😪","😫","😬","😭","😮","😯","😰","😱","😲","😳","😴","😵","😶","😷","🙁","🙂","🙃","🙄","🤐","🤑","🤒","🤓","🤔","🤕","🤠","🤡","🤢","🤣","🤤","🤥","🤧","🤨","🤩","🤪","🤫","🤬","🥺","🤭","🤯","🧐"]; |
|
10847 |
+ $.each(emojis, function(i,e){ |
|
10848 |
+ var emoji = $("<button>"); |
|
10849 |
+ emoji.html(e); |
|
10850 |
+ emoji.on('click', function() { |
|
10851 |
+ var i = textarea.prop('selectionStart'); |
|
10852 |
+ var v = textarea.val(); |
|
10853 |
+ textarea.val(v.substring(0, i) + " " + $(this).html() + v.substring(i, v.length) + " "); |
|
10854 |
+ |
|
10855 |
+ messageContainer.hide(); |
|
10856 |
+ textarea.focus(); |
|
10857 |
+ updateScroll(buddy); |
|
10858 |
+ }); |
|
10859 |
+ menuBar.append(emoji); |
|
10860 |
+ }); |
|
10861 |
+ |
|
10862 |
+ $(".chatMessage,.chatHistory").on('click', function(){ |
|
10863 |
+ messageContainer.hide(); |
|
10864 |
+ }); |
|
10865 |
+ |
|
10866 |
+ messageContainer.empty(); |
|
10867 |
+ messageContainer.append(menuBar); |
|
10868 |
+ |
|
10869 |
+ updateScroll(buddy); |
|
10870 |
+} |
|
10871 |
+ |
|
10872 |
+// My Profile |
|
10873 |
+// ========== |
|
10874 |
+function ShowMyProfileMenu(obj){ |
|
10875 |
+ |
|
10876 |
+ var leftPos = obj.offsetWidth - 254; |
|
10877 |
+ var topPos = obj.offsetHeight + 56 ; |
|
10878 |
+ |
|
10879 |
+ var usrRoleFromDB = getDbItem("userrole", ""); |
|
10880 |
+ if (usrRoleFromDB == "superadmin") { var usrRole = "(superadmin)"; } else { var usrRole = ""; } |
|
10881 |
+ var currentUser = '<font style=\'color:#000000;cursor:auto;\'>' + userName + ' ' + usrRole + '</font>'; |
|
10882 |
+ |
|
10883 |
+ var autoAnswerCheck = AutoAnswerEnabled ? "<i class='fa fa-check' style='float:right;'></i>" : ""; |
|
10884 |
+ var doNotDisturbCheck = DoNotDisturbEnabled ? "<i class='fa fa-check' style='float:right;'></i>" : ""; |
|
10885 |
+ var callWaitingCheck = CallWaitingEnabled ? "<i class='fa fa-check' style='float:right;'></i>" : ""; |
|
10886 |
+ |
|
10887 |
+ var menu = "<div id=userMenu>"; |
|
10888 |
+ menu += "<table id=userMenuTable cellspacing=10 cellpadding=0 style=\"margin-left:auto; margin-right: auto\">"; |
|
10889 |
+ menu += "<tr id=userMenu_1><td><i class=\"fa fa-phone\"></i> "+ lang.auto_answer + "<span id=\"autoAnswerTick\">" + autoAnswerCheck + "</span></td></tr>"; |
|
10890 |
+ menu += "<tr id=userMenu_2><td><i class=\"fa fa-ban\"></i> "+ lang.do_not_disturb + "<span id=\"doNotDisturbTick\">" + doNotDisturbCheck + "</span></td></tr>"; |
|
10891 |
+ menu += "<tr id=userMenu_3><td><i class=\"fa fa-volume-control-phone\"></i> "+ lang.call_waiting + "<span id=\"callWaitingTick\">" + callWaitingCheck + "</span></td></tr>"; |
|
10892 |
+ menu += "<tr id=userMenu_4><td><i class=\"fa fa-refresh\"></i> "+ lang.refresh_registration + "</td></tr>"; |
|
10893 |
+ menu += "<tr id=userMenu_5><td><i class=\"fa fa-user-plus\"></i> "+ lang.add_contact + "</td></tr>"; |
|
10894 |
+ menu += "<tr id=userMenu_6><td><font style=\'color:#000000;cursor:auto;\'>"+ lang.logged_in_as + "</font></td></tr>"; |
|
10895 |
+ menu += "<tr id=userMenu_7><td><span style='width:20px;'></span>" + currentUser + "</td></tr>"; |
|
10896 |
+ menu += "<tr id=userMenu_8><td><i class=\"fa fa-power-off\"></i> "+ lang.log_out + "</td></tr>"; |
|
10897 |
+ menu += "</table>"; |
|
10898 |
+ menu += "</div>"; |
|
10899 |
+ |
|
10900 |
+ $.jeegoopopup.open({ |
|
10901 |
+ html: menu, |
|
10902 |
+ width: 'auto', |
|
10903 |
+ height: 'auto', |
|
10904 |
+ left: '56', |
|
10905 |
+ top: topPos, |
|
10906 |
+ scrolling: 'no', |
|
10907 |
+ skinClass: 'jg_popup_basic', |
|
10908 |
+ innerClass: 'userMenuInner', |
|
10909 |
+ contentClass: 'userMenuContent', |
|
10910 |
+ overlay: true, |
|
10911 |
+ opacity: 0, |
|
10912 |
+ draggable: false, |
|
10913 |
+ resizable: false, |
|
10914 |
+ fadeIn: 0 |
|
10915 |
+ }); |
|
10916 |
+ |
|
10917 |
+ $(window).resize(function() { |
|
10918 |
+ $.jeegoopopup.width('auto').height('auto').left('56').top(topPos); |
|
10919 |
+ }); |
|
10920 |
+ |
|
10921 |
+ $("#userMenu_1").click(function() { |
|
10922 |
+ ToggleAutoAnswer(); |
|
10923 |
+ if (AutoAnswerEnabled) { |
|
10924 |
+ $("#autoAnswerTick").append("<i class='fa fa-check' style='float:right;'></i>"); |
|
10925 |
+ } else { |
|
10926 |
+ $("#autoAnswerTick").empty(); |
|
10927 |
+ } |
|
10928 |
+ }); |
|
10929 |
+ $("#userMenu_2").click(function() { |
|
10930 |
+ ToggleDoNoDisturb(); |
|
10931 |
+ if (DoNotDisturbEnabled) { |
|
10932 |
+ $("#doNotDisturbTick").append("<i class='fa fa-check' style='float:right;'></i>"); |
|
10933 |
+ } else { |
|
10934 |
+ $("#doNotDisturbTick").empty(); |
|
10935 |
+ } |
|
10936 |
+ }); |
|
10937 |
+ $("#userMenu_3").click(function() { |
|
10938 |
+ ToggleCallWaiting(); |
|
10939 |
+ if (CallWaitingEnabled) { |
|
10940 |
+ $("#callWaitingTick").append("<i class='fa fa-check' style='float:right;'></i>"); |
|
10941 |
+ } else { |
|
10942 |
+ $("#callWaitingTick").empty(); |
|
10943 |
+ } |
|
10944 |
+ }); |
|
10945 |
+ $("#userMenu_4").click(function() { RefreshRegistration(); }); |
|
10946 |
+ $("#userMenu_5").click(function() { AddSomeoneWindow(); }); |
|
10947 |
+ $("#userMenu_8").click(function() { SignOut(); }); |
|
10948 |
+ |
|
10949 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
10950 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
10951 |
+} |
|
10952 |
+ |
|
10953 |
+function ShowLaunchVidConfMenu(obj){ |
|
10954 |
+ |
|
10955 |
+ var leftPos = obj.offsetWidth + 121; |
|
10956 |
+ var rightPos = 0; |
|
10957 |
+ var topPos = obj.offsetHeight + 117; |
|
10958 |
+ |
|
10959 |
+ if ($(window).width() <= 915) { |
|
10960 |
+ leftPos = event.pageX + obj.offsetWidth - 113; |
|
10961 |
+ rightPos = 0; |
|
10962 |
+ topPos = event.pageY + obj.offsetHeight - 11; |
|
10963 |
+ } |
|
10964 |
+ |
|
10965 |
+ var vcmenu = "<div id=videoConfMenu>"; |
|
10966 |
+ vcmenu += "<table id=lauchVConfTable cellspacing=0 cellpadding=0 style=\"margin: 0px\">"; |
|
10967 |
+ vcmenu += "<tr id=launchVConfMenu_1><td><i class=\"fa fa-users\"></i> "+ lang.launch_video_conference + "</td></tr>"; |
|
10968 |
+ vcmenu += "</table>"; |
|
10969 |
+ vcmenu += "</div>"; |
|
10970 |
+ |
|
10971 |
+ $.jeegoopopup.open({ |
|
10972 |
+ html: vcmenu, |
|
10973 |
+ width: '228', |
|
10974 |
+ height: '22', |
|
10975 |
+ left: leftPos, |
|
10976 |
+ right: rightPos, |
|
10977 |
+ top: topPos, |
|
10978 |
+ scrolling: 'no', |
|
10979 |
+ skinClass: 'jg_popup_basic', |
|
10980 |
+ overlay: true, |
|
10981 |
+ opacity: 0, |
|
10982 |
+ draggable: false, |
|
10983 |
+ resizable: false, |
|
10984 |
+ fadeIn: 0 |
|
10985 |
+ }); |
|
10986 |
+ |
|
10987 |
+ $(window).resize(function() { |
|
10988 |
+ $.jeegoopopup.width('228').height('22').left(leftPos).top(topPos); |
|
10989 |
+ }); |
|
10990 |
+ |
|
10991 |
+ if ($(window).width() <= 915) { $.jeegoopopup.right(6); } else { $.jeegoopopup.width('228').height('22').left(leftPos).top(topPos); } |
|
10992 |
+ |
|
10993 |
+ $("#launchVConfMenu_1").click(function() { LaunchVideoConference(); $.jeegoopopup.close(); }); |
|
10994 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
10995 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
10996 |
+} |
|
10997 |
+ |
|
10998 |
+function ShowAccountSettingsMenu(obj) { |
|
10999 |
+ |
|
11000 |
+ $.jeegoopopup.close(); |
|
11001 |
+ |
|
11002 |
+ var leftPos = obj.offsetWidth + 212; |
|
11003 |
+ var rightPos = 0; |
|
11004 |
+ var topPos = obj.offsetHeight + 117; |
|
11005 |
+ |
|
11006 |
+ if ($(window).width() <= 915) { |
|
11007 |
+ |
|
11008 |
+ leftPos = event.pageX - 32; |
|
11009 |
+ rightPos = 0; |
|
11010 |
+ topPos = event.pageY + 11; |
|
11011 |
+ } |
|
11012 |
+ |
|
11013 |
+ var setconfmenu = "<div id=settingsCMenu>"; |
|
11014 |
+ setconfmenu += "<table id=lauchSetConfTable cellspacing=0 cellpadding=0 style=\"margin: 0px\">"; |
|
11015 |
+ setconfmenu += "<tr id=settingsCMenu_1><td><i class=\"fa fa-wrench\"></i> "+ lang.account_settings + "</td></tr>"; |
|
11016 |
+ setconfmenu += "</table>"; |
|
11017 |
+ setconfmenu += "</div>"; |
|
11018 |
+ |
|
11019 |
+ $.jeegoopopup.open({ |
|
11020 |
+ html: setconfmenu, |
|
11021 |
+ width: '94', |
|
11022 |
+ height: '22', |
|
11023 |
+ left: leftPos, |
|
11024 |
+ right: rightPos, |
|
11025 |
+ top: topPos, |
|
11026 |
+ scrolling: 'no', |
|
11027 |
+ skinClass: 'jg_popup_basic', |
|
11028 |
+ overlay: true, |
|
11029 |
+ opacity: 0, |
|
11030 |
+ draggable: false, |
|
11031 |
+ resizable: false, |
|
11032 |
+ fadeIn: 0 |
|
11033 |
+ }); |
|
11034 |
+ |
|
11035 |
+ $(window).resize(function() { |
|
11036 |
+ $.jeegoopopup.width('94').height('22').left(leftPos).top(topPos); |
|
11037 |
+ }); |
|
11038 |
+ |
|
11039 |
+ if ($(window).width() <= 915) { $.jeegoopopup.right(6); } else { $.jeegoopopup.width('94').height('22').left(leftPos).top(topPos); } |
|
11040 |
+ |
|
11041 |
+ $("#settingsCMenu_1").click(function() { ConfigureExtensionWindow(); }); |
|
11042 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
11043 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
11044 |
+} |
|
11045 |
+ |
|
11046 |
+function RefreshRegistration(){ |
|
11047 |
+ Unregister(); |
|
11048 |
+ console.log("Unregister complete..."); |
|
11049 |
+ window.setTimeout(function(){ |
|
11050 |
+ console.log("Starting registration..."); |
|
11051 |
+ Register(); |
|
11052 |
+ }, 1000); |
|
11053 |
+} |
|
11054 |
+ |
|
11055 |
+function SignOut() { |
|
11056 |
+ |
|
11057 |
+ if (getDbItem("useRoundcube", "") == 1 && RCLoginCheck == 1) { |
|
11058 |
+ |
|
11059 |
+ // Log out from Roundcube |
|
11060 |
+ $("#roundcubeFrame").remove(); |
|
11061 |
+ $("#rightContent").show(); |
|
11062 |
+ $(".streamSelected").each(function() { $(this).css("display", "none"); }); |
|
11063 |
+ $("#rightContent").append('<iframe id="rcLogoutFrame" name="logoutFrame"></iframe>'); |
|
11064 |
+ |
|
11065 |
+ |
|
11066 |
+ var logoutURL = "https://"+ getDbItem("rcDomain", "") +"/"; |
|
11067 |
+ |
|
11068 |
+ var logoutform = '<form id="rcloForm" method="POST" action="'+ logoutURL +'" target="logoutFrame">'; |
|
11069 |
+ logoutform += '<input type="hidden" name="_action" value="logout" />'; |
|
11070 |
+ logoutform += '<input type="hidden" name="_task" value="logout" />'; |
|
11071 |
+ logoutform += '<input type="hidden" name="_autologout" value="1" />'; |
|
11072 |
+ logoutform += '<input id="submitloButton" type="submit" value="Logout" />'; |
|
11073 |
+ logoutform += '</form>'; |
|
11074 |
+ |
|
11075 |
+ $("#rcLogoutFrame").append(logoutform); |
|
11076 |
+ $("#submitloButton").click(); |
|
11077 |
+ RCLoginCheck == 0; |
|
11078 |
+ } |
|
11079 |
+ |
|
11080 |
+ // Remove the 'uploads' directory used to temporarily store files received during text chat |
|
11081 |
+ removeTextChatUploads(getDbItem("SipUsername", "")); |
|
11082 |
+ |
|
11083 |
+ setTimeout(function() { |
|
11084 |
+ |
|
11085 |
+ // Check if there are any configured external video conference users |
|
11086 |
+ var externalLinks = getDbItem("externalUserConfElem", ""); |
|
11087 |
+ |
|
11088 |
+ if (typeof externalLinks !== 'undefined' && externalLinks != null && externalLinks != 0) { |
|
11089 |
+ |
|
11090 |
+ checkExternalLinks(); |
|
11091 |
+ |
|
11092 |
+ } else { |
|
11093 |
+ Unregister(); |
|
11094 |
+ console.log("Signing Out ..."); |
|
11095 |
+ localStorage.clear(); |
|
11096 |
+ if (winVideoConf != null) { |
|
11097 |
+ winVideoConf.close(); |
|
11098 |
+ } |
|
11099 |
+ window.open('https://' + window.location.host + '/logout.php', '_self'); |
|
11100 |
+ } |
|
11101 |
+ }, 100); |
|
11102 |
+} |
|
11103 |
+ |
|
11104 |
+function ToggleAutoAnswer(){ |
|
11105 |
+ if(AutoAnswerPolicy == "disabled"){ |
|
11106 |
+ AutoAnswerEnabled = false; |
|
11107 |
+ console.warn("Policy AutoAnswer: Disabled"); |
|
11108 |
+ return; |
|
11109 |
+ } |
|
11110 |
+ AutoAnswerEnabled = (AutoAnswerEnabled == true)? false : true; |
|
11111 |
+ if(AutoAnswerPolicy == "enabled") AutoAnswerEnabled = true; |
|
11112 |
+ localDB.setItem("AutoAnswerEnabled", (AutoAnswerEnabled == true)? "1" : "0"); |
|
11113 |
+ console.log("AutoAnswer:", AutoAnswerEnabled); |
|
11114 |
+} |
|
11115 |
+function ToggleDoNoDisturb(){ |
|
11116 |
+ if(DoNotDisturbPolicy == "disabled"){ |
|
11117 |
+ DoNotDisturbEnabled = false; |
|
11118 |
+ console.warn("Policy DoNotDisturb: Disabled"); |
|
11119 |
+ return; |
|
11120 |
+ } |
|
11121 |
+ DoNotDisturbEnabled = (DoNotDisturbEnabled == true)? false : true; |
|
11122 |
+ if(DoNotDisturbPolicy == "enabled") DoNotDisturbEnabled = true; |
|
11123 |
+ localDB.setItem("DoNotDisturbEnabled", (DoNotDisturbEnabled == true)? "1" : "0"); |
|
11124 |
+ $("#dereglink").attr("class", (DoNotDisturbEnabled == true)? "dotDoNotDisturb" : "dotOnline" ); |
|
11125 |
+ console.log("DoNotDisturb", DoNotDisturbEnabled); |
|
11126 |
+} |
|
11127 |
+function ToggleCallWaiting(){ |
|
11128 |
+ if(CallWaitingPolicy == "disabled"){ |
|
11129 |
+ CallWaitingEnabled = false; |
|
11130 |
+ console.warn("Policy CallWaiting: Disabled"); |
|
11131 |
+ return; |
|
11132 |
+ } |
|
11133 |
+ CallWaitingEnabled = (CallWaitingEnabled == true)? false : true; |
|
11134 |
+ if(CallWaitingPolicy == "enabled") CallWaitingPolicy = true; |
|
11135 |
+ localDB.setItem("CallWaitingEnabled", (CallWaitingEnabled == true)? "1" : "0"); |
|
11136 |
+ console.log("CallWaiting", CallWaitingEnabled); |
|
11137 |
+} |
|
11138 |
+function ToggleRecordAllCalls(){ |
|
11139 |
+ if(CallRecordingPolicy == "disabled"){ |
|
11140 |
+ RecordAllCalls = false; |
|
11141 |
+ console.warn("Policy CallRecording: Disabled"); |
|
11142 |
+ return; |
|
11143 |
+ } |
|
11144 |
+ RecordAllCalls = (RecordAllCalls == true)? false : true; |
|
11145 |
+ if(CallRecordingPolicy == "enabled") RecordAllCalls = true; |
|
11146 |
+ localDB.setItem("RecordAllCalls", (RecordAllCalls == true)? "1" : "0"); |
|
11147 |
+ console.log("RecordAllCalls", RecordAllCalls); |
|
11148 |
+} |
|
11149 |
+ |
|
11150 |
+function ShowBuddyProfileMenu(buddy, obj, typeStr){ |
|
11151 |
+ |
|
11152 |
+ $.jeegoopopup.close(); |
|
11153 |
+ |
|
11154 |
+ leftPos = event.pageX - 60; |
|
11155 |
+ topPos = event.pageY + 45; |
|
11156 |
+ |
|
11157 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
11158 |
+ |
|
11159 |
+ if (typeStr == "extension") { |
|
11160 |
+ |
|
11161 |
+ var html = "<div style=\"width:200px; cursor:pointer\" onclick=\"EditBuddyWindow('"+ buddy +"')\">"; |
|
11162 |
+ html += "<div class=\"buddyProfilePic\" style=\"background-image:url('"+ getPicture(buddy, "extension") +"')\"></div>"; |
|
11163 |
+ html += "<div id=ProfileInfo style=\"text-align:center\"><i class=\"fa fa-spinner fa-spin\"></i></div>" |
|
11164 |
+ html += "</div>"; |
|
11165 |
+ |
|
11166 |
+ $.jeegoopopup.open({ |
|
11167 |
+ html: html, |
|
11168 |
+ width: '200', |
|
11169 |
+ height: 'auto', |
|
11170 |
+ left: leftPos, |
|
11171 |
+ top: topPos, |
|
11172 |
+ scrolling: 'no', |
|
11173 |
+ skinClass: 'jg_popup_basic', |
|
11174 |
+ contentClass: 'showContactDetails', |
|
11175 |
+ overlay: true, |
|
11176 |
+ opacity: 0, |
|
11177 |
+ draggable: true, |
|
11178 |
+ resizable: false, |
|
11179 |
+ fadeIn: 0 |
|
11180 |
+ }); |
|
11181 |
+ |
|
11182 |
+ // Done |
|
11183 |
+ $("#ProfileInfo").html(""); |
|
11184 |
+ |
|
11185 |
+ $("#ProfileInfo").append("<div class=ProfileTextLarge style=\"margin-top:15px\">"+ buddyObj.CallerIDName +"</div>"); |
|
11186 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.Desc +"</div>"); |
|
11187 |
+ |
|
11188 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.extension_number +":</div>"); |
|
11189 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.ExtNo +" </div>"); |
|
11190 |
+ |
|
11191 |
+ if(buddyObj.Email && buddyObj.Email != "null" && buddyObj.Email != "undefined"){ |
|
11192 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.email +":</div>"); |
|
11193 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.Email +" </div>"); |
|
11194 |
+ } |
|
11195 |
+ if(buddyObj.MobileNumber && buddyObj.MobileNumber != "null" && buddyObj.MobileNumber != "undefined"){ |
|
11196 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.mobile +":</div>"); |
|
11197 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.MobileNumber +" </div>"); |
|
11198 |
+ } |
|
11199 |
+ if(buddyObj.ContactNumber1 && buddyObj.ContactNumber1 != "null" && buddyObj.ContactNumber1 != "undefined"){ |
|
11200 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.alternative_contact +":</div>"); |
|
11201 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.ContactNumber1 +" </div>"); |
|
11202 |
+ } |
|
11203 |
+ if(buddyObj.ContactNumber2 && buddyObj.ContactNumber2 != "null" && buddyObj.ContactNumber2 != "undefined"){ |
|
11204 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.alternative_contact +":</div>"); |
|
11205 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.ContactNumber2 +" </div>"); |
|
11206 |
+ } |
|
11207 |
+ |
|
11208 |
+ } else if (typeStr == "contact") { |
|
11209 |
+ |
|
11210 |
+ var html = "<div style=\"width:200px; cursor:pointer\" onclick=\"EditBuddyWindow('"+ buddy +"')\">"; |
|
11211 |
+ html += "<div class=\"buddyProfilePic\" style=\"background-image:url('"+ getPicture(buddy, "contact") +"')\"></div>"; |
|
11212 |
+ html += "<div id=ProfileInfo style=\"text-align:center\"><i class=\"fa fa-spinner fa-spin\"></i></div>" |
|
11213 |
+ html += "</div>"; |
|
11214 |
+ |
|
11215 |
+ $.jeegoopopup.open({ |
|
11216 |
+ html: html, |
|
11217 |
+ width: '200', |
|
11218 |
+ height: 'auto', |
|
11219 |
+ left: leftPos, |
|
11220 |
+ top: topPos, |
|
11221 |
+ scrolling: 'no', |
|
11222 |
+ skinClass: 'jg_popup_basic', |
|
11223 |
+ contentClass: 'showContactDetails', |
|
11224 |
+ overlay: true, |
|
11225 |
+ opacity: 0, |
|
11226 |
+ draggable: true, |
|
11227 |
+ resizable: false, |
|
11228 |
+ fadeIn: 0 |
|
11229 |
+ }); |
|
11230 |
+ |
|
11231 |
+ $("#ProfileInfo").html(""); |
|
11232 |
+ $("#ProfileInfo").append("<div class=ProfileTextLarge style=\"margin-top:15px\">"+ buddyObj.CallerIDName +"</div>"); |
|
11233 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.Desc +"</div>"); |
|
11234 |
+ |
|
11235 |
+ if(buddyObj.Email && buddyObj.Email != "null" && buddyObj.Email != "undefined"){ |
|
11236 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.email +":</div>"); |
|
11237 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.Email +" </div>"); |
|
11238 |
+ } |
|
11239 |
+ if(buddyObj.MobileNumber && buddyObj.MobileNumber != "null" && buddyObj.MobileNumber != "undefined"){ |
|
11240 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.mobile +":</div>"); |
|
11241 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.MobileNumber +" </div>"); |
|
11242 |
+ } |
|
11243 |
+ if(buddyObj.ContactNumber1 && buddyObj.ContactNumber1 != "null" && buddyObj.ContactNumber1 != "undefined"){ |
|
11244 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.alternative_contact +":</div>"); |
|
11245 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.ContactNumber1 +" </div>"); |
|
11246 |
+ } |
|
11247 |
+ if(buddyObj.ContactNumber2 && buddyObj.ContactNumber2 != "null" && buddyObj.ContactNumber2 != "undefined"){ |
|
11248 |
+ $("#ProfileInfo").append("<div class=ProfileTextSmall style=\"margin-top:15px\">"+ lang.alternative_contact +":</div>"); |
|
11249 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.ContactNumber2 +" </div>"); |
|
11250 |
+ } |
|
11251 |
+ |
|
11252 |
+ } else if (typeStr == "group") { |
|
11253 |
+ |
|
11254 |
+ var html = "<div style=\"width:200px; cursor:pointer\" onclick=\"EditBuddyWindow('"+ buddy +"')\">"; |
|
11255 |
+ html += "<div class=\"buddyProfilePic\" style=\"background-image:url('"+ getPicture(buddy, "group") +"')\"></div>"; |
|
11256 |
+ html += "<div id=ProfileInfo style=\"text-align:center\"><i class=\"fa fa-spinner fa-spin\"></i></div>" |
|
11257 |
+ html += "</div>"; |
|
11258 |
+ |
|
11259 |
+ $.jeegoopopup.open({ |
|
11260 |
+ html: html, |
|
11261 |
+ width: '200', |
|
11262 |
+ height: 'auto', |
|
11263 |
+ left: leftPos, |
|
11264 |
+ top: topPos, |
|
11265 |
+ scrolling: 'no', |
|
11266 |
+ skinClass: 'jg_popup_basic', |
|
11267 |
+ contentClass: 'showContactDetails', |
|
11268 |
+ overlay: true, |
|
11269 |
+ opacity: 0, |
|
11270 |
+ draggable: true, |
|
11271 |
+ resizable: false, |
|
11272 |
+ fadeIn: 0 |
|
11273 |
+ }); |
|
11274 |
+ |
|
11275 |
+ $("#ProfileInfo").html(""); |
|
11276 |
+ |
|
11277 |
+ $("#ProfileInfo").append("<div class=ProfileTextLarge style=\"margin-top:15px\">"+ buddyObj.CallerIDName +"</div>"); |
|
11278 |
+ $("#ProfileInfo").append("<div class=ProfileTextMedium>"+ buddyObj.Desc +"</div>"); |
|
11279 |
+ } |
|
11280 |
+ |
|
11281 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
11282 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
11283 |
+} |
|
11284 |
+ |
|
11285 |
+// Device and Settings |
|
11286 |
+// =================== |
|
11287 |
+function ChangeSettings(lineNum, obj){ |
|
11288 |
+ |
|
11289 |
+ var leftPos = event.pageX - 138; |
|
11290 |
+ var topPos = event.pageY + 28; |
|
11291 |
+ |
|
11292 |
+ if (($(window).height() - event.pageY) < 300) { topPos = event.pageY - 170; } |
|
11293 |
+ |
|
11294 |
+ // Check if you are in a call |
|
11295 |
+ var lineObj = FindLineByNumber(lineNum); |
|
11296 |
+ if(lineObj == null || lineObj.SipSession == null) return; |
|
11297 |
+ var session = lineObj.SipSession; |
|
11298 |
+ |
|
11299 |
+ var html = "<div id=DeviceSelector style=\"width:250px\"></div>"; |
|
11300 |
+ |
|
11301 |
+ $.jeegoopopup.open({ |
|
11302 |
+ html: html, |
|
11303 |
+ width: "auto", |
|
11304 |
+ height: "auto", |
|
11305 |
+ left: leftPos, |
|
11306 |
+ top: topPos, |
|
11307 |
+ scrolling: 'no', |
|
11308 |
+ skinClass: 'jg_popup_basic', |
|
11309 |
+ contentClass: 'callSettingsContent', |
|
11310 |
+ overlay: true, |
|
11311 |
+ opacity: 0, |
|
11312 |
+ draggable: true, |
|
11313 |
+ resizable: false, |
|
11314 |
+ fadeIn: 0 |
|
11315 |
+ }); |
|
11316 |
+ |
|
11317 |
+ var audioSelect = $('<select/>'); |
|
11318 |
+ audioSelect.prop("id", "audioSrcSelect"); |
|
11319 |
+ audioSelect.css("width", "100%"); |
|
11320 |
+ |
|
11321 |
+ var videoSelect = $('<select/>'); |
|
11322 |
+ videoSelect.prop("id", "videoSrcSelect"); |
|
11323 |
+ videoSelect.css("width", "100%"); |
|
11324 |
+ |
|
11325 |
+ var speakerSelect = $('<select/>'); |
|
11326 |
+ speakerSelect.prop("id", "audioOutputSelect"); |
|
11327 |
+ speakerSelect.css("width", "100%"); |
|
11328 |
+ |
|
11329 |
+ var ringerSelect = $('<select/>'); |
|
11330 |
+ ringerSelect.prop("id", "ringerSelect"); |
|
11331 |
+ ringerSelect.css("width", "100%"); |
|
11332 |
+ |
|
11333 |
+ // Handle Audio Source changes (Microphone) |
|
11334 |
+ audioSelect.change(function() { |
|
11335 |
+ |
|
11336 |
+ console.log("Call to change Microphone: ", this.value); |
|
11337 |
+ |
|
11338 |
+ // First Stop Recording the call |
|
11339 |
+ var mustRestartRecording = false; |
|
11340 |
+ if(session.data.mediaRecorder && session.data.mediaRecorder.state == "recording"){ |
|
11341 |
+ StopRecording(lineNum, true); |
|
11342 |
+ mustRestartRecording = true; |
|
11343 |
+ } |
|
11344 |
+ |
|
11345 |
+ // Stop Monitoring |
|
11346 |
+ if(lineObj.LocalSoundMeter) lineObj.LocalSoundMeter.stop(); |
|
11347 |
+ |
|
11348 |
+ // Save Setting |
|
11349 |
+ session.data.AudioSourceDevice = this.value; |
|
11350 |
+ |
|
11351 |
+ var constraints = { |
|
11352 |
+ audio: { |
|
11353 |
+ deviceId: (this.value != "default")? { exact: this.value } : "default" |
|
11354 |
+ }, |
|
11355 |
+ video: false |
|
11356 |
+ } |
|
11357 |
+ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ |
|
11358 |
+ // Assume that since we are selecting from a dropdown, this is possible |
|
11359 |
+ var newMediaTrack = newStream.getAudioTracks()[0]; |
|
11360 |
+ var pc = session.sessionDescriptionHandler.peerConnection; |
|
11361 |
+ pc.getSenders().forEach(function (RTCRtpSender) { |
|
11362 |
+ if(RTCRtpSender.track && RTCRtpSender.track.kind == "audio") { |
|
11363 |
+ console.log("Switching Audio Track : "+ RTCRtpSender.track.label + " to "+ newMediaTrack.label); |
|
11364 |
+ RTCRtpSender.track.stop(); // Must stop, or this mic will stay in use |
|
11365 |
+ RTCRtpSender.replaceTrack(newMediaTrack).then(function(){ |
|
11366 |
+ // Start recording again |
|
11367 |
+ if(mustRestartRecording) StartRecording(lineNum); |
|
11368 |
+ // Monitor audio stream |
|
11369 |
+ lineObj.LocalSoundMeter = StartLocalAudioMediaMonitoring(lineNum, session); |
|
11370 |
+ }).catch(function(e){ |
|
11371 |
+ console.error("Error replacing track: ", e); |
|
11372 |
+ }); |
|
11373 |
+ } |
|
11374 |
+ }); |
|
11375 |
+ }).catch(function(e){ |
|
11376 |
+ console.error("Error on getUserMedia"); |
|
11377 |
+ }); |
|
11378 |
+ }); |
|
11379 |
+ |
|
11380 |
+ // Handle output change (speaker) |
|
11381 |
+ speakerSelect.change(function() { |
|
11382 |
+ console.log("Call to change Speaker: ", this.value); |
|
11383 |
+ |
|
11384 |
+ // Save Setting |
|
11385 |
+ session.data.AudioOutputDevice = this.value; |
|
11386 |
+ |
|
11387 |
+ // Also change the sinkId |
|
11388 |
+ // ====================== |
|
11389 |
+ var sinkId = this.value; |
|
11390 |
+ console.log("Attempting to set Audio Output SinkID for line "+ lineNum +" [" + sinkId + "]"); |
|
11391 |
+ |
|
11392 |
+ // Remote audio |
|
11393 |
+ var element = $("#line-"+ lineNum +"-remoteAudio").get(0); |
|
11394 |
+ if (element) { |
|
11395 |
+ if (typeof element.sinkId !== 'undefined') { |
|
11396 |
+ element.setSinkId(sinkId).then(function(){ |
|
11397 |
+ console.log("sinkId applied: "+ sinkId); |
|
11398 |
+ }).catch(function(e){ |
|
11399 |
+ console.warn("Error using setSinkId: ", e); |
|
11400 |
+ }); |
|
11401 |
+ } else { |
|
11402 |
+ console.warn("setSinkId() is not possible using this browser.") |
|
11403 |
+ } |
|
11404 |
+ } |
|
11405 |
+ }); |
|
11406 |
+ |
|
11407 |
+ // Handle video input change (WebCam) |
|
11408 |
+ videoSelect.change(function(){ |
|
11409 |
+ console.log("Call to change WebCam"); |
|
11410 |
+ |
|
11411 |
+ switchVideoSource(lineNum, this.value); |
|
11412 |
+ }); |
|
11413 |
+ |
|
11414 |
+ // Load Devices |
|
11415 |
+ if(!navigator.mediaDevices) { |
|
11416 |
+ console.warn("navigator.mediaDevices not possible."); |
|
11417 |
+ return; |
|
11418 |
+ } |
|
11419 |
+ |
|
11420 |
+ for (var i = 0; i < AudioinputDevices.length; ++i) { |
|
11421 |
+ var deviceInfo = AudioinputDevices[i]; |
|
11422 |
+ var devideId = deviceInfo.deviceId; |
|
11423 |
+ var DisplayName = (deviceInfo.label)? deviceInfo.label : ""; |
|
11424 |
+ if(DisplayName.indexOf("(") > 0) DisplayName = DisplayName.substring(0,DisplayName.indexOf("(")); |
|
11425 |
+ |
|
11426 |
+ // Create Option |
|
11427 |
+ var option = $('<option/>'); |
|
11428 |
+ option.prop("value", devideId); |
|
11429 |
+ option.text((DisplayName != "")? DisplayName : "Microphone"); |
|
11430 |
+ if(session.data.AudioSourceDevice == devideId) option.prop("selected", true); |
|
11431 |
+ audioSelect.append(option); |
|
11432 |
+ } |
|
11433 |
+ for (var i = 0; i < VideoinputDevices.length; ++i) { |
|
11434 |
+ var deviceInfo = VideoinputDevices[i]; |
|
11435 |
+ var devideId = deviceInfo.deviceId; |
|
11436 |
+ var DisplayName = (deviceInfo.label)? deviceInfo.label : ""; |
|
11437 |
+ if(DisplayName.indexOf("(") > 0) DisplayName = DisplayName.substring(0,DisplayName.indexOf("(")); |
|
11438 |
+ |
|
11439 |
+ // Create Option |
|
11440 |
+ var option = $('<option/>'); |
|
11441 |
+ option.prop("value", devideId); |
|
11442 |
+ option.text((DisplayName != "")? DisplayName : "Webcam"); |
|
11443 |
+ if(session.data.VideoSourceDevice == devideId) option.prop("selected", true); |
|
11444 |
+ videoSelect.append(option); |
|
11445 |
+ } |
|
11446 |
+ if(HasSpeakerDevice){ |
|
11447 |
+ for (var i = 0; i < SpeakerDevices.length; ++i) { |
|
11448 |
+ var deviceInfo = SpeakerDevices[i]; |
|
11449 |
+ var devideId = deviceInfo.deviceId; |
|
11450 |
+ var DisplayName = (deviceInfo.label)? deviceInfo.label : ""; |
|
11451 |
+ if(DisplayName.indexOf("(") > 0) DisplayName = DisplayName.substring(0,DisplayName.indexOf("(")); |
|
11452 |
+ |
|
11453 |
+ // Create Option |
|
11454 |
+ var option = $('<option/>'); |
|
11455 |
+ option.prop("value", devideId); |
|
11456 |
+ option.text((DisplayName != "")? DisplayName : "Speaker"); |
|
11457 |
+ if(session.data.AudioOutputDevice == devideId) option.prop("selected", true); |
|
11458 |
+ speakerSelect.append(option); |
|
11459 |
+ } |
|
11460 |
+ } |
|
11461 |
+ |
|
11462 |
+ // Mic Serttings |
|
11463 |
+ $("#DeviceSelector").append("<div class=callSettingsDvs>"+ lang.microphone +": </div>"); |
|
11464 |
+ $("#DeviceSelector").append(audioSelect); |
|
11465 |
+ |
|
11466 |
+ // Speaker |
|
11467 |
+ if(HasSpeakerDevice){ |
|
11468 |
+ $("#DeviceSelector").append("<div class=callSettingsDvs>"+ lang.speaker +": </div>"); |
|
11469 |
+ $("#DeviceSelector").append(speakerSelect); |
|
11470 |
+ } |
|
11471 |
+ // Camera |
|
11472 |
+ if(session.data.withvideo == true){ |
|
11473 |
+ $("#DeviceSelector").append("<div class=callSettingsDvs>"+ lang.camera +": </div>"); |
|
11474 |
+ $("#DeviceSelector").append(videoSelect); |
|
11475 |
+ } |
|
11476 |
+ |
|
11477 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
11478 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
11479 |
+} |
|
11480 |
+ |
|
11481 |
+// Media Presentation |
|
11482 |
+// ================== |
|
11483 |
+function PresentCamera(lineNum){ |
|
11484 |
+ var lineObj = FindLineByNumber(lineNum); |
|
11485 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
11486 |
+ console.warn("Line or Session is Null."); |
|
11487 |
+ return; |
|
11488 |
+ } |
|
11489 |
+ var session = lineObj.SipSession; |
|
11490 |
+ |
|
11491 |
+ $("#line-"+ lineNum +"-src-camera").prop("disabled", true); |
|
11492 |
+ $("#line-"+ lineNum +"-src-canvas").prop("disabled", false); |
|
11493 |
+ $("#line-"+ lineNum +"-src-desktop").prop("disabled", false); |
|
11494 |
+ $("#line-"+ lineNum +"-src-video").prop("disabled", false); |
|
11495 |
+ $("#line-"+ lineNum +"-src-blank").prop("disabled", false); |
|
11496 |
+ |
|
11497 |
+ $("#line-"+ lineNum + "-scratchpad-container").hide(); |
|
11498 |
+ RemoveScratchpad(lineNum); |
|
11499 |
+ $("#line-"+ lineNum +"-sharevideo").hide(); |
|
11500 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).pause(); |
|
11501 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).removeAttribute('src'); |
|
11502 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).load(); |
|
11503 |
+ window.clearInterval(session.data.videoResampleInterval); |
|
11504 |
+ |
|
11505 |
+ $("#line-"+ lineNum + "-localVideo").show(); |
|
11506 |
+ $("#line-"+ lineNum + "-remoteVideo").appendTo("#line-"+ lineNum + "-stage-container"); |
|
11507 |
+ |
|
11508 |
+ switchVideoSource(lineNum, session.data.VideoSourceDevice); |
|
11509 |
+} |
|
11510 |
+function PresentScreen(lineNum){ |
|
11511 |
+ var lineObj = FindLineByNumber(lineNum); |
|
11512 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
11513 |
+ console.warn("Line or Session is Null."); |
|
11514 |
+ return; |
|
11515 |
+ } |
|
11516 |
+ var session = lineObj.SipSession; |
|
11517 |
+ |
|
11518 |
+ $("#line-"+ lineNum +"-src-camera").prop("disabled", false); |
|
11519 |
+ $("#line-"+ lineNum +"-src-canvas").prop("disabled", false); |
|
11520 |
+ $("#line-"+ lineNum +"-src-desktop").prop("disabled", true); |
|
11521 |
+ $("#line-"+ lineNum +"-src-video").prop("disabled", false); |
|
11522 |
+ $("#line-"+ lineNum +"-src-blank").prop("disabled", false); |
|
11523 |
+ |
|
11524 |
+ $("#line-"+ lineNum + "-scratchpad-container").hide(); |
|
11525 |
+ RemoveScratchpad(lineNum); |
|
11526 |
+ $("#line-"+ lineNum +"-sharevideo").hide(); |
|
11527 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).pause(); |
|
11528 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).removeAttribute('src'); |
|
11529 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).load(); |
|
11530 |
+ window.clearInterval(session.data.videoResampleInterval); |
|
11531 |
+ |
|
11532 |
+ $("#line-"+ lineNum + "-localVideo").hide(); |
|
11533 |
+ $("#line-"+ lineNum + "-remoteVideo").appendTo("#line-"+ lineNum + "-stage-container"); |
|
11534 |
+ |
|
11535 |
+ ShareScreen(lineNum); |
|
11536 |
+} |
|
11537 |
+function PresentScratchpad(lineNum){ |
|
11538 |
+ var lineObj = FindLineByNumber(lineNum); |
|
11539 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
11540 |
+ console.warn("Line or Session is Null."); |
|
11541 |
+ return; |
|
11542 |
+ } |
|
11543 |
+ var session = lineObj.SipSession; |
|
11544 |
+ |
|
11545 |
+ $("#line-"+ lineNum +"-src-camera").prop("disabled", false); |
|
11546 |
+ $("#line-"+ lineNum +"-src-canvas").prop("disabled", true); |
|
11547 |
+ $("#line-"+ lineNum +"-src-desktop").prop("disabled", false); |
|
11548 |
+ $("#line-"+ lineNum +"-src-video").prop("disabled", false); |
|
11549 |
+ $("#line-"+ lineNum +"-src-blank").prop("disabled", false); |
|
11550 |
+ |
|
11551 |
+ $("#line-"+ lineNum + "-scratchpad-container").hide(); |
|
11552 |
+ RemoveScratchpad(lineNum); |
|
11553 |
+ $("#line-"+ lineNum +"-sharevideo").hide(); |
|
11554 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).pause(); |
|
11555 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).removeAttribute('src'); |
|
11556 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).load(); |
|
11557 |
+ window.clearInterval(session.data.videoResampleInterval); |
|
11558 |
+ |
|
11559 |
+ $("#line-"+ lineNum + "-localVideo").hide(); |
|
11560 |
+ $("#line-"+ lineNum + "-remoteVideo").appendTo("#line-"+ lineNum + "-preview-container"); |
|
11561 |
+ |
|
11562 |
+ SendCanvas(lineNum); |
|
11563 |
+} |
|
11564 |
+function PresentVideo(lineNum){ |
|
11565 |
+ |
|
11566 |
+ var lineObj = FindLineByNumber(lineNum); |
|
11567 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
11568 |
+ console.warn("Line or Session is Null."); |
|
11569 |
+ return; |
|
11570 |
+ } |
|
11571 |
+ var session = lineObj.SipSession; |
|
11572 |
+ |
|
11573 |
+ $.jeegoopopup.close(); |
|
11574 |
+ |
|
11575 |
+ var presentVideoHtml = "<div>"; |
|
11576 |
+ presentVideoHtml += '<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
11577 |
+ presentVideoHtml += "<label for=SelectVideoToSend class=customBrowseButton style=\"display: block; margin: 26px auto;\">Select File</label>"; |
|
11578 |
+ presentVideoHtml += "<div class=\"UiWindowField\"><input type=file accept=\"video/*\" id=SelectVideoToSend></div>"; |
|
11579 |
+ presentVideoHtml += "</div>"; |
|
11580 |
+ |
|
11581 |
+ $.jeegoopopup.open({ |
|
11582 |
+ html: presentVideoHtml, |
|
11583 |
+ width: '180', |
|
11584 |
+ height: '80', |
|
11585 |
+ center: true, |
|
11586 |
+ scrolling: 'no', |
|
11587 |
+ skinClass: 'jg_popup_basic', |
|
11588 |
+ overlay: true, |
|
11589 |
+ opacity: 0, |
|
11590 |
+ draggable: true, |
|
11591 |
+ resizable: false, |
|
11592 |
+ fadeIn: 0 |
|
11593 |
+ }); |
|
11594 |
+ |
|
11595 |
+ $("#SelectVideoToSend").on('change', function(event){ |
|
11596 |
+ var input = event.target; |
|
11597 |
+ if(input.files.length >= 1){ |
|
11598 |
+ |
|
11599 |
+ $.jeegoopopup.close(); |
|
11600 |
+ |
|
11601 |
+ // Send Video (Can only send one file) |
|
11602 |
+ SendVideo(lineNum, URL.createObjectURL(input.files[0])); |
|
11603 |
+ } |
|
11604 |
+ else { |
|
11605 |
+ console.warn("Please Select a file to present."); |
|
11606 |
+ } |
|
11607 |
+ }); |
|
11608 |
+ |
|
11609 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); }); |
|
11610 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); }); |
|
11611 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); } }); |
|
11612 |
+} |
|
11613 |
+function PresentBlank(lineNum){ |
|
11614 |
+ var lineObj = FindLineByNumber(lineNum); |
|
11615 |
+ if(lineObj == null || lineObj.SipSession == null){ |
|
11616 |
+ console.warn("Line or Session is Null."); |
|
11617 |
+ return; |
|
11618 |
+ } |
|
11619 |
+ var session = lineObj.SipSession; |
|
11620 |
+ |
|
11621 |
+ $("#line-"+ lineNum +"-src-camera").prop("disabled", false); |
|
11622 |
+ $("#line-"+ lineNum +"-src-canvas").prop("disabled", false); |
|
11623 |
+ $("#line-"+ lineNum +"-src-desktop").prop("disabled", false); |
|
11624 |
+ $("#line-"+ lineNum +"-src-video").prop("disabled", false); |
|
11625 |
+ $("#line-"+ lineNum +"-src-blank").prop("disabled", true); |
|
11626 |
+ |
|
11627 |
+ $("#line-"+ lineNum + "-scratchpad-container").hide(); |
|
11628 |
+ RemoveScratchpad(lineNum); |
|
11629 |
+ $("#line-"+ lineNum +"-sharevideo").hide(); |
|
11630 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).pause(); |
|
11631 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).removeAttribute('src'); |
|
11632 |
+ $("#line-"+ lineNum +"-sharevideo").get(0).load(); |
|
11633 |
+ window.clearInterval(session.data.videoResampleInterval); |
|
11634 |
+ |
|
11635 |
+ $("#line-"+ lineNum + "-localVideo").hide(); |
|
11636 |
+ $("#line-"+ lineNum + "-remoteVideo").appendTo("#line-"+ lineNum + "-stage-container"); |
|
11637 |
+ |
|
11638 |
+ DisableVideoStream(lineNum); |
|
11639 |
+} |
|
11640 |
+function RemoveScratchpad(lineNum){ |
|
11641 |
+ var scratchpad = GetCanvas("line-" + lineNum + "-scratchpad"); |
|
11642 |
+ if(scratchpad != null){ |
|
11643 |
+ window.clearInterval(scratchpad.redrawIntrtval); |
|
11644 |
+ |
|
11645 |
+ RemoveCanvas("line-" + lineNum + "-scratchpad"); |
|
11646 |
+ $("#line-"+ lineNum + "-scratchpad-container").empty(); |
|
11647 |
+ |
|
11648 |
+ scratchpad = null; |
|
11649 |
+ } |
|
11650 |
+} |
|
11651 |
+ |
|
11652 |
+// Call Statistics |
|
11653 |
+// =============== |
|
11654 |
+function ShowCallStats(lineNum, obj){ |
|
11655 |
+ console.log("Show Call Stats"); |
|
11656 |
+ $("#line-"+ lineNum +"-AudioStats").show(300); |
|
11657 |
+} |
|
11658 |
+function HideCallStats(lineNum, obj){ |
|
11659 |
+ console.log("Hide Call Stats"); |
|
11660 |
+ $("#line-"+ lineNum +"-AudioStats").hide(300); |
|
11661 |
+} |
|
11662 |
+ |
|
11663 |
+// Chatting |
|
11664 |
+// ======== |
|
11665 |
+function chatOnbeforepaste(event, obj, buddy){ |
|
11666 |
+ console.log("Handle paste, checking for Images..."); |
|
11667 |
+ var items = (event.clipboardData || event.originalEvent.clipboardData).items; |
|
11668 |
+ |
|
11669 |
+ // Find pasted image among pasted items |
|
11670 |
+ var preventDefault = false; |
|
11671 |
+ for (var i = 0; i < items.length; i++) { |
|
11672 |
+ if (items[i].type.indexOf("image") === 0) { |
|
11673 |
+ console.log("Image found! Opening image editor..."); |
|
11674 |
+ |
|
11675 |
+ var blob = items[i].getAsFile(); |
|
11676 |
+ |
|
11677 |
+ // Read the image in |
|
11678 |
+ var reader = new FileReader(); |
|
11679 |
+ reader.onload = function (event) { |
|
11680 |
+ |
|
11681 |
+ // Image has loaded, open Image Preview Editor |
|
11682 |
+ // =========================================== |
|
11683 |
+ console.log("Image loaded... setting placeholder..."); |
|
11684 |
+ var placeholderImage = new Image(); |
|
11685 |
+ placeholderImage.onload = function () { |
|
11686 |
+ |
|
11687 |
+ console.log("Placeholder loaded... CreateImageEditor..."); |
|
11688 |
+ |
|
11689 |
+ CreateImageEditor(buddy, placeholderImage); |
|
11690 |
+ } |
|
11691 |
+ placeholderImage.src = event.target.result; |
|
11692 |
+ } |
|
11693 |
+ reader.readAsDataURL(blob); |
|
11694 |
+ |
|
11695 |
+ preventDefault = true; |
|
11696 |
+ continue; |
|
11697 |
+ } |
|
11698 |
+ } |
|
11699 |
+ |
|
11700 |
+ // Pevent default if you found an image |
|
11701 |
+ if (preventDefault) event.preventDefault(); |
|
11702 |
+} |
|
11703 |
+function chatOnkeydown(event, obj, buddy) { |
|
11704 |
+ |
|
11705 |
+ var keycode = (event.keyCode ? event.keyCode : event.which); |
|
11706 |
+ if (keycode == '13'){ |
|
11707 |
+ if(event.ctrlKey) { |
|
11708 |
+ SendChatMessage(buddy); |
|
11709 |
+ return false; |
|
11710 |
+ } |
|
11711 |
+ } |
|
11712 |
+} |
|
11713 |
+ |
|
11714 |
+function ReformatMessage(str) { |
|
11715 |
+ var msg = str; |
|
11716 |
+ // Simple tex=>HTML |
|
11717 |
+ msg = msg.replace(/</gi, "<"); |
|
11718 |
+ msg = msg.replace(/>/gi, ">"); |
|
11719 |
+ msg = msg.replace(/\n/gi, "<br>"); |
|
11720 |
+ // Emojy |
|
11721 |
+ // Skype: :) :( :D :O ;) ;( (:| :| :P :$ :^) |-) |-( :x ]:) |
|
11722 |
+ // (cool) (hearteyes) (stareyes) (like) (unamused) (cwl) (xd) (pensive) (weary) (hysterical) (flushed) (sweatgrinning) (disappointed) (loudlycrying) (shivering) (expressionless) (relieved) (inlove) (kiss) (yawn) (puke) (doh) (angry) (wasntme) (worry) (confused) (veryconfused) (mm) (nerd) (rainbowsmile) (devil) (angel) (envy) (makeup) (think) (rofl) (happy) (smirk) (nod) (shake) (waiting) (emo) (donttalk) (idea) (talk) (swear) (headbang) (learn) (headphones) (morningafter) (selfie) (shock) (ttm) (dream) |
|
11723 |
+ msg = msg.replace(/(:\)|:\-\)|:o\))/g, String.fromCodePoint(0x1F642)); // :) :-) :o) |
|
11724 |
+ msg = msg.replace(/(:\(|:\-\(|:o\()/g, String.fromCodePoint(0x1F641)); // :( :-( :o( |
|
11725 |
+ msg = msg.replace(/(;\)|;\-\)|;o\))/g, String.fromCodePoint(0x1F609)); // ;) ;-) ;o) |
|
11726 |
+ msg = msg.replace(/(:'\(|:'\-\()/g, String.fromCodePoint(0x1F62A)); // :'( :'‑( |
|
11727 |
+ msg = msg.replace(/(:'\(|:'\-\()/g, String.fromCodePoint(0x1F602)); // :') :'‑) |
|
11728 |
+ msg = msg.replace(/(:\$)/g, String.fromCodePoint(0x1F633)); // :$ |
|
11729 |
+ msg = msg.replace(/(>:\()/g, String.fromCodePoint(0x1F623)); // >:( |
|
11730 |
+ msg = msg.replace(/(:\×)/g, String.fromCodePoint(0x1F618)); // :× |
|
11731 |
+ msg = msg.replace(/(:\O|:\‑O)/g, String.fromCodePoint(0x1F632)); // :O :‑O |
|
11732 |
+ msg = msg.replace(/(:P|:\-P|:p|:\-p)/g, String.fromCodePoint(0x1F61B)); // :P :-P :p :-p |
|
11733 |
+ msg = msg.replace(/(;P|;\-P|;p|;\-p)/g, String.fromCodePoint(0x1F61C)); // ;P ;-P ;p ;-p |
|
11734 |
+ msg = msg.replace(/(:D|:\-D)/g, String.fromCodePoint(0x1F60D)); // :D :-D |
|
11735 |
+ |
|
11736 |
+ msg = msg.replace(/(\(like\))/g, String.fromCodePoint(0x1F44D)); // (like) |
|
11737 |
+ |
|
11738 |
+ // Make clickable Hyperlinks |
|
11739 |
+ msg = msg.replace(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/gi, function (x) { |
|
11740 |
+ var niceLink = (x.length > 50) ? x.substring(0, 47) + "..." : x; |
|
11741 |
+ var rtn = "<A target=_blank class=previewHyperlink href=\"" + x + "\">" + niceLink + "</A>"; |
|
11742 |
+ return rtn; |
|
11743 |
+ }); |
|
11744 |
+ return msg; |
|
11745 |
+} |
|
11746 |
+function getPicture(buddy, typestr){ |
|
11747 |
+ if(buddy == "profilePicture"){ |
|
11748 |
+ // Special handling for profile image |
|
11749 |
+ var dbImg = localDB.getItem("profilePicture"); |
|
11750 |
+ if(dbImg == null){ |
|
11751 |
+ return hostingPrefex + "images/default.png"; |
|
11752 |
+ } |
|
11753 |
+ else { |
|
11754 |
+ return dbImg; |
|
11755 |
+ } |
|
11756 |
+ } |
|
11757 |
+ |
|
11758 |
+ typestr = (typestr)? typestr : "extension"; |
|
11759 |
+ |
|
11760 |
+ var buddyObj = FindBuddyByIdentity(buddy); |
|
11761 |
+ if(buddyObj.imageObjectURL != ""){ |
|
11762 |
+ // Use Cache |
|
11763 |
+ return buddyObj.imageObjectURL; |
|
11764 |
+ } |
|
11765 |
+ |
|
11766 |
+ var dbImg = localDB.getItem("img-"+ buddy +"-"+ typestr); |
|
11767 |
+ |
|
11768 |
+ if(dbImg == null){ |
|
11769 |
+ return hostingPrefex + "images/default.png"; |
|
11770 |
+ } else { |
|
11771 |
+ buddyObj.imageObjectURL = URL.createObjectURL(base64toBlob(dbImg, 'image/png')); |
|
11772 |
+ return buddyObj.imageObjectURL; |
|
11773 |
+ } |
|
11774 |
+} |
|
11775 |
+ |
|
11776 |
+// Image Editor |
|
11777 |
+// ============ |
|
11778 |
+function CreateImageEditor(buddy, placeholderImage){ |
|
11779 |
+ // Show Interface |
|
11780 |
+ // ============== |
|
11781 |
+ console.log("Setting Up ImageEditor..."); |
|
11782 |
+ if($("#contact-" + buddy + "-imagePastePreview").is(":visible")) { |
|
11783 |
+ console.log("Resetting ImageEditor..."); |
|
11784 |
+ $("#contact-" + buddy + "-imagePastePreview").empty(); |
|
11785 |
+ RemoveCanvas("contact-" + buddy + "-imageCanvas") |
|
11786 |
+ } else { |
|
11787 |
+ $("#contact-" + buddy + "-imagePastePreview").show(); |
|
11788 |
+ } |
|
11789 |
+ // Create UI |
|
11790 |
+ // ========= |
|
11791 |
+ var toolBarDiv = $('<div/>'); |
|
11792 |
+ toolBarDiv.css("margin-bottom", "5px") |
|
11793 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Select" onclick="ImageEditor_Select(\''+ buddy +'\')"><i class="fa fa-mouse-pointer"></i></button>'); |
|
11794 |
+ toolBarDiv.append(' | '); |
|
11795 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Draw" onclick="ImageEditor_FreedrawPen(\''+ buddy +'\')"><i class="fa fa-pencil"></i></button>'); |
|
11796 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Paint" onclick="ImageEditor_FreedrawPaint(\''+ buddy +'\')"><i class="fa fa-paint-brush"></i></button>'); |
|
11797 |
+ toolBarDiv.append(' | '); |
|
11798 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Select Line Color" onclick="ImageEditor_SetectLineColor(\''+ buddy +'\')"><i class="fa fa-pencil-square-o" style="color:rgb(255, 0, 0)"></i></button>'); |
|
11799 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Select Fill Color" onclick="ImageEditor_SetectFillColor(\''+ buddy +'\')"><i class="fa fa-pencil-square" style="color:rgb(255, 0, 0)"></i></button>'); |
|
11800 |
+ toolBarDiv.append(' | '); |
|
11801 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Add Circle" onclick="ImageEditor_AddCircle(\''+ buddy +'\')"><i class="fa fa-circle"></i></button>'); |
|
11802 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Add Rectangle" onclick="ImageEditor_AddRectangle(\''+ buddy +'\')"><i class="fa fa-stop"></i></button>'); |
|
11803 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Add Triangle" onclick="ImageEditor_AddTriangle(\''+ buddy +'\')"><i class="fa fa-play"></i></button>'); |
|
11804 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Add Emoji" onclick="ImageEditor_SetectEmoji(\''+ buddy +'\')"><i class="fa fa-smile-o"></i></button>'); |
|
11805 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Add Text" onclick="ImageEditor_AddText(\''+ buddy +'\')"><i class="fa fa-font"></i></button>'); |
|
11806 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Delete Selected Items" onclick="ImageEditor_Clear(\''+ buddy +'\')"><i class="fa fa-times"></i></button>'); |
|
11807 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Clear All" onclick="ImageEditor_ClearAll(\''+ buddy +'\')"><i class="fa fa-trash"></i></button>'); |
|
11808 |
+ toolBarDiv.append(' | '); |
|
11809 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Pan" onclick="ImageEditor_Pan(\''+ buddy +'\')"><i class="fa fa-hand-paper-o"></i></button>'); |
|
11810 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Zoom In" onclick="ImageEditor_ZoomIn(\''+ buddy +'\')"><i class="fa fa-search-plus"></i></button>'); |
|
11811 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Zoom Out" onclick="ImageEditor_ZoomOut(\''+ buddy +'\')"><i class="fa fa-search-minus"></i></button>'); |
|
11812 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Reset Pan & Zoom" onclick="ImageEditor_ResetZoom(\''+ buddy +'\')"><i class="fa fa-search" aria-hidden="true"></i></button>'); |
|
11813 |
+ toolBarDiv.append(' | '); |
|
11814 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Cancel" onclick="ImageEditor_Cancel(\''+ buddy +'\')"><i class="fa fa-times-circle"></i></button>'); |
|
11815 |
+ toolBarDiv.append('<button class="toolBarButtons" title="Send" onclick="ImageEditor_Send(\''+ buddy +'\')"><i class="fa fa-paper-plane"></i></button>'); |
|
11816 |
+ $("#contact-" + buddy + "-imagePastePreview").append(toolBarDiv); |
|
11817 |
+ |
|
11818 |
+ // Create the canvas |
|
11819 |
+ // ================= |
|
11820 |
+ var newCanvas = $('<canvas/>'); |
|
11821 |
+ newCanvas.prop("id", "contact-" + buddy + "-imageCanvas"); |
|
11822 |
+ newCanvas.css("border", "1px solid #CCCCCC"); |
|
11823 |
+ $("#contact-" + buddy + "-imagePastePreview").append(newCanvas); |
|
11824 |
+ console.log("Canvas for ImageEditor created..."); |
|
11825 |
+ |
|
11826 |
+ var imgWidth = placeholderImage.width; |
|
11827 |
+ var imgHeight = placeholderImage.height; |
|
11828 |
+ var maxWidth = $("#contact-" + buddy + "-imagePastePreview").width()-2; // for the border |
|
11829 |
+ var maxHeight = 480; |
|
11830 |
+ $("#contact-" + buddy + "-imageCanvas").prop("width", maxWidth); |
|
11831 |
+ $("#contact-" + buddy + "-imageCanvas").prop("height", maxHeight); |
|
11832 |
+ |
|
11833 |
+ // Handle Initial Zoom |
|
11834 |
+ var zoomToFitImage = 1; |
|
11835 |
+ var zoomWidth = 1; |
|
11836 |
+ var zoomHeight = 1; |
|
11837 |
+ if(imgWidth > maxWidth || imgHeight > maxHeight) |
|
11838 |
+ { |
|
11839 |
+ if(imgWidth > maxWidth) |
|
11840 |
+ { |
|
11841 |
+ zoomWidth = (maxWidth / imgWidth); |
|
11842 |
+ } |
|
11843 |
+ if(imgHeight > maxHeight) |
|
11844 |
+ { |
|
11845 |
+ zoomHeight = (maxHeight / imgHeight); |
|
11846 |
+ console.log("Scale to fit height: "+ zoomHeight); |
|
11847 |
+ } |
|
11848 |
+ zoomToFitImage = Math.min(zoomWidth, zoomHeight) // need the smallest because less is more zoom. |
|
11849 |
+ console.log("Scale down to fit: "+ zoomToFitImage); |
|
11850 |
+ |
|
11851 |
+ // Shape the canvas to fit the image and the new zoom |
|
11852 |
+ imgWidth = imgWidth * zoomToFitImage; |
|
11853 |
+ imgHeight = imgHeight * zoomToFitImage; |
|
11854 |
+ console.log("resizing canvas to fit new image size..."); |
|
11855 |
+ $("#contact-" + buddy + "-imageCanvas").prop("width", imgWidth); |
|
11856 |
+ $("#contact-" + buddy + "-imageCanvas").prop("height", imgHeight); |
|
11857 |
+ } |
|
11858 |
+ else { |
|
11859 |
+ console.log("Image is able to fit, resizing canvas..."); |
|
11860 |
+ $("#contact-" + buddy + "-imageCanvas").prop("width", imgWidth); |
|
11861 |
+ $("#contact-" + buddy + "-imageCanvas").prop("height", imgHeight); |
|
11862 |
+ } |
|
11863 |
+ |
|
11864 |
+ // Fabric Canvas API |
|
11865 |
+ // ================= |
|
11866 |
+ console.log("Creating fabric API..."); |
|
11867 |
+ var canvas = new fabric.Canvas("contact-" + buddy + "-imageCanvas"); |
|
11868 |
+ canvas.id = "contact-" + buddy + "-imageCanvas"; |
|
11869 |
+ canvas.ToolSelected = "None"; |
|
11870 |
+ canvas.PenColour = "rgb(255, 0, 0)"; |
|
11871 |
+ canvas.PenWidth = 2; |
|
11872 |
+ canvas.PaintColour = "rgba(227, 230, 3, 0.6)"; |
|
11873 |
+ canvas.PaintWidth = 10; |
|
11874 |
+ canvas.FillColour = "rgb(255, 0, 0)"; |
|
11875 |
+ canvas.isDrawingMode = false; |
|
11876 |
+ |
|
11877 |
+ canvas.selectionColor = 'rgba(112,179,233,0.25)'; |
|
11878 |
+ canvas.selectionBorderColor = 'rgba(112,179,233, 0.8)'; |
|
11879 |
+ canvas.selectionLineWidth = 1; |
|
11880 |
+ |
|
11881 |
+ // Zoom to fit Width or Height |
|
11882 |
+ // =========================== |
|
11883 |
+ canvas.setZoom(zoomToFitImage); |
|
11884 |
+ |
|
11885 |
+ // Canvas Events |
|
11886 |
+ // ============= |
|
11887 |
+ canvas.on('mouse:down', function(opt) { |
|
11888 |
+ var evt = opt.e; |
|
11889 |
+ |
|
11890 |
+ if (this.ToolSelected == "Pan") { |
|
11891 |
+ this.isDragging = true; |
|
11892 |
+ this.selection = false; |
|
11893 |
+ this.lastPosX = evt.clientX; |
|
11894 |
+ this.lastPosY = evt.clientY; |
|
11895 |
+ } |
|
11896 |
+ // Make nicer grab handles |
|
11897 |
+ if(opt.target != null){ |
|
11898 |
+ if(evt.altKey === true) |
|
11899 |
+ { |
|
11900 |
+ opt.target.lockMovementX = true; |
|
11901 |
+ } |
|
11902 |
+ if(evt.shiftKey === true) |
|
11903 |
+ { |
|
11904 |
+ opt.target.lockMovementY = true; |
|
11905 |
+ } |
|
11906 |
+ opt.target.set({ |
|
11907 |
+ transparentCorners: false, |
|
11908 |
+ borderColor: 'rgba(112,179,233, 0.4)', |
|
11909 |
+ cornerColor: 'rgba(112,179,233, 0.8)', |
|
11910 |
+ cornerSize: 6 |
|
11911 |
+ }); |
|
11912 |
+ } |
|
11913 |
+ }); |
|
11914 |
+ canvas.on('mouse:move', function(opt) { |
|
11915 |
+ if (this.isDragging) { |
|
11916 |
+ var e = opt.e; |
|
11917 |
+ this.viewportTransform[4] += e.clientX - this.lastPosX; |
|
11918 |
+ this.viewportTransform[5] += e.clientY - this.lastPosY; |
|
11919 |
+ this.requestRenderAll(); |
|
11920 |
+ this.lastPosX = e.clientX; |
|
11921 |
+ this.lastPosY = e.clientY; |
|
11922 |
+ } |
|
11923 |
+ }); |
|
11924 |
+ canvas.on('mouse:up', function(opt) { |
|
11925 |
+ this.isDragging = false; |
|
11926 |
+ this.selection = true; |
|
11927 |
+ if(opt.target != null){ |
|
11928 |
+ opt.target.lockMovementX = false; |
|
11929 |
+ opt.target.lockMovementY = false; |
|
11930 |
+ } |
|
11931 |
+ }); |
|
11932 |
+ canvas.on('mouse:wheel', function(opt) { |
|
11933 |
+ var delta = opt.e.deltaY; |
|
11934 |
+ var pointer = canvas.getPointer(opt.e); |
|
11935 |
+ var zoom = canvas.getZoom(); |
|
11936 |
+ zoom = zoom + delta/200; |
|
11937 |
+ if (zoom > 10) zoom = 10; |
|
11938 |
+ if (zoom < 0.1) zoom = 0.1; |
|
11939 |
+ canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom); |
|
11940 |
+ opt.e.preventDefault(); |
|
11941 |
+ opt.e.stopPropagation(); |
|
11942 |
+ }); |
|
11943 |
+ |
|
11944 |
+ // Add Image |
|
11945 |
+ // ========== |
|
11946 |
+ canvas.backgroundImage = new fabric.Image(placeholderImage); |
|
11947 |
+ |
|
11948 |
+ CanvasCollection.push(canvas); |
|
11949 |
+ |
|
11950 |
+ // Add Key Press Events |
|
11951 |
+ // ==================== |
|
11952 |
+ $("#contact-" + buddy + "-imagePastePreview").keydown(function(evt) { |
|
11953 |
+ evt = evt || window.event; |
|
11954 |
+ var key = evt.keyCode; |
|
11955 |
+ console.log("Key press on Image Editor ("+ buddy +"): "+ key); |
|
11956 |
+ |
|
11957 |
+ // Delete Key |
|
11958 |
+ if (key == 46) ImageEditor_Clear(buddy); |
|
11959 |
+ }); |
|
11960 |
+ |
|
11961 |
+ console.log("ImageEditor: "+ canvas.id +" created"); |
|
11962 |
+ |
|
11963 |
+ ImageEditor_FreedrawPen(buddy); |
|
11964 |
+} |
|
11965 |
+function GetCanvas(canvasId){ |
|
11966 |
+ for(var c = 0; c < CanvasCollection.length; c++){ |
|
11967 |
+ try { |
|
11968 |
+ if(CanvasCollection[c].id == canvasId) return CanvasCollection[c]; |
|
11969 |
+ } catch(e) { |
|
11970 |
+ console.warn("CanvasCollection.id not available"); |
|
11971 |
+ } |
|
11972 |
+ } |
|
11973 |
+ return null; |
|
11974 |
+} |
|
11975 |
+function RemoveCanvas(canvasId){ |
|
11976 |
+ for(var c = 0; c < CanvasCollection.length; c++){ |
|
11977 |
+ try{ |
|
11978 |
+ if(CanvasCollection[c].id == canvasId) { |
|
11979 |
+ console.log("Found Old Canvas, Disposing..."); |
|
11980 |
+ |
|
11981 |
+ CanvasCollection[c].clear() |
|
11982 |
+ CanvasCollection[c].dispose(); |
|
11983 |
+ |
|
11984 |
+ CanvasCollection[c].id = "--deleted--"; |
|
11985 |
+ |
|
11986 |
+ console.log("CanvasCollection.splice("+ c +", 1)"); |
|
11987 |
+ CanvasCollection.splice(c, 1); |
|
11988 |
+ break; |
|
11989 |
+ } |
|
11990 |
+ } |
|
11991 |
+ catch(e){ } |
|
11992 |
+ } |
|
11993 |
+ console.log("There are "+ CanvasCollection.length +" canvas now."); |
|
11994 |
+} |
|
11995 |
+var ImageEditor_Select = function (buddy){ |
|
11996 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
11997 |
+ if(canvas != null) { |
|
11998 |
+ canvas.ToolSelected = "none"; |
|
11999 |
+ canvas.isDrawingMode = false; |
|
12000 |
+ return true; |
|
12001 |
+ } |
|
12002 |
+ return false; |
|
12003 |
+} |
|
12004 |
+var ImageEditor_FreedrawPen = function (buddy){ |
|
12005 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12006 |
+ if(canvas != null) { |
|
12007 |
+ canvas.freeDrawingBrush.color = canvas.PenColour; |
|
12008 |
+ canvas.freeDrawingBrush.width = canvas.PenWidth; |
|
12009 |
+ canvas.ToolSelected = "Draw"; |
|
12010 |
+ canvas.isDrawingMode = true; |
|
12011 |
+ console.log(canvas) |
|
12012 |
+ return true; |
|
12013 |
+ } |
|
12014 |
+ return false; |
|
12015 |
+} |
|
12016 |
+var ImageEditor_FreedrawPaint = function (buddy){ |
|
12017 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12018 |
+ if(canvas != null) { |
|
12019 |
+ canvas.freeDrawingBrush.color = canvas.PaintColour; |
|
12020 |
+ canvas.freeDrawingBrush.width = canvas.PaintWidth; |
|
12021 |
+ canvas.ToolSelected = "Paint"; |
|
12022 |
+ canvas.isDrawingMode = true; |
|
12023 |
+ return true; |
|
12024 |
+ } |
|
12025 |
+ return false; |
|
12026 |
+} |
|
12027 |
+var ImageEditor_Pan = function (buddy){ |
|
12028 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12029 |
+ if(canvas != null) { |
|
12030 |
+ canvas.ToolSelected = "Pan"; |
|
12031 |
+ canvas.isDrawingMode = false; |
|
12032 |
+ return true; |
|
12033 |
+ } |
|
12034 |
+ return false; |
|
12035 |
+} |
|
12036 |
+var ImageEditor_ResetZoom = function (buddy){ |
|
12037 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12038 |
+ if(canvas != null) { |
|
12039 |
+ canvas.setZoom(1); |
|
12040 |
+ canvas.setViewportTransform([1,0,0,1,0,0]); |
|
12041 |
+ return true; |
|
12042 |
+ } |
|
12043 |
+ return false; |
|
12044 |
+} |
|
12045 |
+var ImageEditor_ZoomIn = function (buddy){ |
|
12046 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12047 |
+ if(canvas != null) { |
|
12048 |
+ var zoom = canvas.getZoom(); |
|
12049 |
+ zoom = zoom + 0.5; |
|
12050 |
+ if (zoom > 10) zoom = 10; |
|
12051 |
+ if (zoom < 0.1) zoom = 0.1; |
|
12052 |
+ |
|
12053 |
+ var point = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2); |
|
12054 |
+ var center = fabric.util.transformPoint(point, canvas.viewportTransform); |
|
12055 |
+ |
|
12056 |
+ canvas.zoomToPoint(point, zoom); |
|
12057 |
+ |
|
12058 |
+ return true; |
|
12059 |
+ } |
|
12060 |
+ return false; |
|
12061 |
+} |
|
12062 |
+var ImageEditor_ZoomOut = function (buddy){ |
|
12063 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12064 |
+ if(canvas != null) { |
|
12065 |
+ var zoom = canvas.getZoom(); |
|
12066 |
+ zoom = zoom - 0.5; |
|
12067 |
+ if (zoom > 10) zoom = 10; |
|
12068 |
+ if (zoom < 0.1) zoom = 0.1; |
|
12069 |
+ |
|
12070 |
+ var point = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2); |
|
12071 |
+ var center = fabric.util.transformPoint(point, canvas.viewportTransform); |
|
12072 |
+ |
|
12073 |
+ canvas.zoomToPoint(point, zoom); |
|
12074 |
+ |
|
12075 |
+ return true; |
|
12076 |
+ } |
|
12077 |
+ return false; |
|
12078 |
+} |
|
12079 |
+var ImageEditor_AddCircle = function (buddy){ |
|
12080 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12081 |
+ if(canvas != null) { |
|
12082 |
+ canvas.ToolSelected = "none"; |
|
12083 |
+ canvas.isDrawingMode = false; |
|
12084 |
+ var circle = new fabric.Circle({ |
|
12085 |
+ radius: 20, fill: canvas.FillColour |
|
12086 |
+ }) |
|
12087 |
+ canvas.add(circle); |
|
12088 |
+ canvas.centerObject(circle); |
|
12089 |
+ canvas.setActiveObject(circle); |
|
12090 |
+ return true; |
|
12091 |
+ } |
|
12092 |
+ return false; |
|
12093 |
+} |
|
12094 |
+var ImageEditor_AddRectangle = function (buddy){ |
|
12095 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12096 |
+ if(canvas != null) { |
|
12097 |
+ canvas.ToolSelected = "none"; |
|
12098 |
+ canvas.isDrawingMode = false; |
|
12099 |
+ var rectangle = new fabric.Rect({ |
|
12100 |
+ width: 40, height: 40, fill: canvas.FillColour |
|
12101 |
+ }) |
|
12102 |
+ canvas.add(rectangle); |
|
12103 |
+ canvas.centerObject(rectangle); |
|
12104 |
+ canvas.setActiveObject(rectangle); |
|
12105 |
+ return true; |
|
12106 |
+ } |
|
12107 |
+ return false; |
|
12108 |
+} |
|
12109 |
+var ImageEditor_AddTriangle = function (buddy){ |
|
12110 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12111 |
+ if(canvas != null) { |
|
12112 |
+ canvas.ToolSelected = "none"; |
|
12113 |
+ canvas.isDrawingMode = false; |
|
12114 |
+ var triangle = new fabric.Triangle({ |
|
12115 |
+ width: 40, height: 40, fill: canvas.FillColour |
|
12116 |
+ }) |
|
12117 |
+ canvas.add(triangle); |
|
12118 |
+ canvas.centerObject(triangle); |
|
12119 |
+ canvas.setActiveObject(triangle); |
|
12120 |
+ return true; |
|
12121 |
+ } |
|
12122 |
+ return false; |
|
12123 |
+} |
|
12124 |
+var ImageEditor_AddEmoji = function (buddy){ |
|
12125 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12126 |
+ if(canvas != null) { |
|
12127 |
+ canvas.ToolSelected = "none"; |
|
12128 |
+ canvas.isDrawingMode = false; |
|
12129 |
+ var text = new fabric.Text(String.fromCodePoint(0x1F642), { fontSize : 24 }); |
|
12130 |
+ canvas.add(text); |
|
12131 |
+ canvas.centerObject(text); |
|
12132 |
+ canvas.setActiveObject(text); |
|
12133 |
+ return true; |
|
12134 |
+ } |
|
12135 |
+ return false; |
|
12136 |
+} |
|
12137 |
+var ImageEditor_AddText = function (buddy, textString){ |
|
12138 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12139 |
+ if(canvas != null) { |
|
12140 |
+ canvas.ToolSelected = "none"; |
|
12141 |
+ canvas.isDrawingMode = false; |
|
12142 |
+ var text = new fabric.IText(textString, { fill: canvas.FillColour, fontFamily: 'arial', fontSize : 18 }); |
|
12143 |
+ canvas.add(text); |
|
12144 |
+ canvas.centerObject(text); |
|
12145 |
+ canvas.setActiveObject(text); |
|
12146 |
+ return true; |
|
12147 |
+ } |
|
12148 |
+ return false; |
|
12149 |
+} |
|
12150 |
+var ImageEditor_Clear = function (buddy){ |
|
12151 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12152 |
+ if(canvas != null) { |
|
12153 |
+ canvas.ToolSelected = "none"; |
|
12154 |
+ canvas.isDrawingMode = false; |
|
12155 |
+ |
|
12156 |
+ var activeObjects = canvas.getActiveObjects(); |
|
12157 |
+ for (var i=0; i<activeObjects.length; i++){ |
|
12158 |
+ canvas.remove(activeObjects[i]); |
|
12159 |
+ } |
|
12160 |
+ canvas.discardActiveObject(); |
|
12161 |
+ |
|
12162 |
+ return true; |
|
12163 |
+ } |
|
12164 |
+ return false; |
|
12165 |
+} |
|
12166 |
+var ImageEditor_ClearAll = function (buddy){ |
|
12167 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12168 |
+ if(canvas != null) { |
|
12169 |
+ var savedBgImage = canvas.backgroundImage; |
|
12170 |
+ |
|
12171 |
+ canvas.ToolSelected = "none"; |
|
12172 |
+ canvas.isDrawingMode = false; |
|
12173 |
+ canvas.clear(); |
|
12174 |
+ |
|
12175 |
+ canvas.backgroundImage = savedBgImage; |
|
12176 |
+ return true; |
|
12177 |
+ } |
|
12178 |
+ return false; |
|
12179 |
+} |
|
12180 |
+var ImageEditor_Cancel = function (buddy){ |
|
12181 |
+ console.log("Removing ImageEditor..."); |
|
12182 |
+ |
|
12183 |
+ $("#contact-" + buddy + "-imagePastePreview").empty(); |
|
12184 |
+ RemoveCanvas("contact-" + buddy + "-imageCanvas"); |
|
12185 |
+ $("#contact-" + buddy + "-imagePastePreview").hide(); |
|
12186 |
+} |
|
12187 |
+var ImageEditor_Send = function (buddy){ |
|
12188 |
+ var canvas = GetCanvas("contact-" + buddy + "-imageCanvas"); |
|
12189 |
+ if(canvas != null) { |
|
12190 |
+ var imgData = canvas.toDataURL({ format: 'png' }); |
|
12191 |
+ SendImageDataMessage(buddy, imgData); |
|
12192 |
+ return true; |
|
12193 |
+ } |
|
12194 |
+ return false; |
|
12195 |
+} |
|
12196 |
+ |
|
12197 |
+// Find something in the message stream |
|
12198 |
+// ==================================== |
|
12199 |
+function FindSomething(buddy) { |
|
12200 |
+ $("#contact-" + buddy + "-search").toggle(); |
|
12201 |
+ if($("#contact-" + buddy + "-search").is(":visible") == false){ |
|
12202 |
+ RefreshStream(FindBuddyByIdentity(buddy)); |
|
12203 |
+ } |
|
12204 |
+ updateScroll(buddy); |
|
12205 |
+} |
|
12206 |
+ |
|
12207 |
+// FileShare an Upload |
|
12208 |
+// =================== |
|
12209 |
+var allowDradAndDrop = function() { |
|
12210 |
+ var div = document.createElement('div'); |
|
12211 |
+ return (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && 'FormData' in window && 'FileReader' in window; |
|
12212 |
+} |
|
12213 |
+function onFileDragDrop(e, buddy){ |
|
12214 |
+ |
|
12215 |
+ var filesArray = e.dataTransfer.files; |
|
12216 |
+ console.log("You are about to upload " + filesArray.length + " file."); |
|
12217 |
+ |
|
12218 |
+ // Clear style |
|
12219 |
+ $("#contact-"+ buddy +"-ChatHistory").css("outline", "none"); |
|
12220 |
+ |
|
12221 |
+ for (var f = 0; f < filesArray.length; f++){ |
|
12222 |
+ var fileObj = filesArray[f]; |
|
12223 |
+ var reader = new FileReader(); |
|
12224 |
+ reader.onload = function (event) { |
|
12225 |
+ |
|
12226 |
+ // Check if the file is under 50MB |
|
12227 |
+ if(fileObj.size <= 52428800){ |
|
12228 |
+ // Add to Stream |
|
12229 |
+ // ============= |
|
12230 |
+ SendFileDataMessage(buddy, event.target.result, fileObj.name, fileObj.size); |
|
12231 |
+ } |
|
12232 |
+ else{ |
|
12233 |
+ alert("The file '"+ fileObj.name +"' is bigger than 50MB, you cannot upload this file") |
|
12234 |
+ } |
|
12235 |
+ } |
|
12236 |
+ console.log("Adding: "+ fileObj.name + " of size: "+ fileObj.size +"bytes"); |
|
12237 |
+ reader.readAsDataURL(fileObj); |
|
12238 |
+ } |
|
12239 |
+ |
|
12240 |
+ // Prevent Default |
|
12241 |
+ preventDefault(e); |
|
12242 |
+} |
|
12243 |
+function cancelDragDrop(e, buddy){ |
|
12244 |
+ // dragleave dragend |
|
12245 |
+ $("#contact-"+ buddy +"-ChatHistory").css("outline", "none"); |
|
12246 |
+ preventDefault(e); |
|
12247 |
+} |
|
12248 |
+function setupDragDrop(e, buddy){ |
|
12249 |
+ // dragover dragenter |
|
12250 |
+ $("#contact-"+ buddy +"-ChatHistory").css("outline", "2px dashed #184369"); |
|
12251 |
+ preventDefault(e); |
|
12252 |
+} |
|
12253 |
+function preventDefault(e){ |
|
12254 |
+ e.preventDefault(); |
|
12255 |
+ e.stopPropagation(); |
|
12256 |
+} |
|
12257 |
+ |
|
12258 |
+// UI Elements |
|
12259 |
+// =========== |
|
12260 |
+function Alert(messageStr, TitleStr, onOk) { |
|
12261 |
+ |
|
12262 |
+ $("#jg_popup_l").empty(); |
|
12263 |
+ $("#jg_popup_b").empty(); |
|
12264 |
+ $("#windowCtrls").empty(); |
|
12265 |
+ $.jeegoopopup.close(); |
|
12266 |
+ |
|
12267 |
+ var html = "<div class=NoSelect>"; |
|
12268 |
+ html += '<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
12269 |
+ html += "<div class=UiText style=\"padding: 0px 10px 8px 10px;\" id=AllertMessageText>" + messageStr + "</div>"; |
|
12270 |
+ html += "</div>" |
|
12271 |
+ |
|
12272 |
+ $.jeegoopopup.open({ |
|
12273 |
+ title: TitleStr, |
|
12274 |
+ html: html, |
|
12275 |
+ width: '260', |
|
12276 |
+ height: 'auto', |
|
12277 |
+ center: true, |
|
12278 |
+ scrolling: 'no', |
|
12279 |
+ skinClass: 'jg_popup_basic', |
|
12280 |
+ contentClass: 'confirmDelContact', |
|
12281 |
+ overlay: true, |
|
12282 |
+ opacity: 50, |
|
12283 |
+ draggable: true, |
|
12284 |
+ resizable: false, |
|
12285 |
+ fadeIn: 0 |
|
12286 |
+ }); |
|
12287 |
+ |
|
12288 |
+ $("#jg_popup_b").append("<div id=bottomButtons><button id=AlertOkButton style=\"width:80px\">"+ lang.ok +"</button></div>"); |
|
12289 |
+ |
|
12290 |
+ $("#AlertOkButton").click(function () { |
|
12291 |
+ console.log("Alert OK clicked"); |
|
12292 |
+ if (onOk) onOk(); |
|
12293 |
+ }); |
|
12294 |
+ |
|
12295 |
+ $(window).resize(function() { |
|
12296 |
+ $.jeegoopopup.center(); |
|
12297 |
+ }); |
|
12298 |
+ |
|
12299 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12300 |
+ $("#AlertOkButton").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12301 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12302 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); |
|
12303 |
+ |
|
12304 |
+} |
|
12305 |
+function AlertConfigExtWindow(messageStr, TitleStr) { |
|
12306 |
+ |
|
12307 |
+ $("#jg_popup_l").empty(); |
|
12308 |
+ $("#jg_popup_b").empty(); |
|
12309 |
+ $("#windowCtrls").empty(); |
|
12310 |
+ $.jeegoopopup.close(); |
|
12311 |
+ |
|
12312 |
+ videoAudioCheck = 1; |
|
12313 |
+ |
|
12314 |
+ var html = "<div class=NoSelect>"; |
|
12315 |
+ html += '<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
12316 |
+ html += "<div class=UiText style=\"padding: 10px\" id=AllertMessageText>" + messageStr + "</div>"; |
|
12317 |
+ html += "</div>" |
|
12318 |
+ |
|
12319 |
+ $.jeegoopopup.open({ |
|
12320 |
+ title: TitleStr, |
|
12321 |
+ html: html, |
|
12322 |
+ width: '260', |
|
12323 |
+ height: 'auto', |
|
12324 |
+ center: true, |
|
12325 |
+ scrolling: 'no', |
|
12326 |
+ skinClass: 'jg_popup_basic', |
|
12327 |
+ contentClass: 'confirmDelContact', |
|
12328 |
+ overlay: true, |
|
12329 |
+ opacity: 50, |
|
12330 |
+ draggable: true, |
|
12331 |
+ resizable: false, |
|
12332 |
+ fadeIn: 0 |
|
12333 |
+ }); |
|
12334 |
+ |
|
12335 |
+ $("#jg_popup_b").append("<div id=bottomButtons><button id=AlertOkButton style=\"width:80px\">"+ lang.ok +"</button></div>"); |
|
12336 |
+ |
|
12337 |
+ $(window).resize(function() { |
|
12338 |
+ $.jeegoopopup.center(); |
|
12339 |
+ }); |
|
12340 |
+ |
|
12341 |
+ $("#closeImg").click(function() { $("#windowCtrls").empty(); $("#jg_popup_b").empty(); $.jeegoopopup.close(); ConfigureExtensionWindow(); }); |
|
12342 |
+ $("#AlertOkButton").click(function() { console.log("Alert OK clicked"); $("#windowCtrls").empty(); $("#jg_popup_b").empty(); $.jeegoopopup.close(); ConfigureExtensionWindow(); }); |
|
12343 |
+ $("#jg_popup_overlay").click(function() { $("#windowCtrls").empty(); $("#jg_popup_b").empty(); $.jeegoopopup.close(); ConfigureExtensionWindow(); }); |
|
12344 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $("#windowCtrls").empty(); $("#jg_popup_b").empty(); $.jeegoopopup.close(); ConfigureExtensionWindow(); } }); |
|
12345 |
+ |
|
12346 |
+} |
|
12347 |
+function Confirm(messageStr, TitleStr, onOk, onCancel) { |
|
12348 |
+ |
|
12349 |
+ $("#jg_popup_l").empty(); |
|
12350 |
+ $("#jg_popup_b").empty(); |
|
12351 |
+ $("#windowCtrls").empty(); |
|
12352 |
+ $.jeegoopopup.close(); |
|
12353 |
+ |
|
12354 |
+ var html = "<div class=NoSelect>"; |
|
12355 |
+ html += '<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
12356 |
+ html += "<div class=UiText style=\"padding: 10px\" id=ConfirmMessageText>" + messageStr + "</div>"; |
|
12357 |
+ html += "</div>"; |
|
12358 |
+ |
|
12359 |
+ $.jeegoopopup.open({ |
|
12360 |
+ html: html, |
|
12361 |
+ width: '260', |
|
12362 |
+ height: 'auto', |
|
12363 |
+ center: true, |
|
12364 |
+ scrolling: 'no', |
|
12365 |
+ skinClass: 'jg_popup_basic', |
|
12366 |
+ contentClass: 'confirmDelContact', |
|
12367 |
+ overlay: true, |
|
12368 |
+ opacity: 50, |
|
12369 |
+ draggable: true, |
|
12370 |
+ resizable: false, |
|
12371 |
+ fadeIn: 0 |
|
12372 |
+ }); |
|
12373 |
+ |
|
12374 |
+ $("#jg_popup_b").append("<div id=ConfDelContact><button id=ConfirmOkButton>"+ lang.ok +"</button><button id=ConfirmCancelButton>"+ lang.cancel +"</button></div>"); |
|
12375 |
+ |
|
12376 |
+ $("#ConfirmOkButton").click(function () { |
|
12377 |
+ console.log("Confirm OK clicked"); |
|
12378 |
+ if (onOk) onOk(); |
|
12379 |
+ }); |
|
12380 |
+ $("#ConfirmCancelButton").click(function () { |
|
12381 |
+ console.log("Confirm Cancel clicked"); |
|
12382 |
+ if (onCancel) onCancel(); |
|
12383 |
+ }); |
|
12384 |
+ |
|
12385 |
+ $(window).resize(function() { |
|
12386 |
+ $.jeegoopopup.center(); |
|
12387 |
+ }); |
|
12388 |
+ |
|
12389 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12390 |
+ $("#ConfirmOkButton").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12391 |
+ $("#ConfirmCancelButton").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12392 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12393 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); |
|
12394 |
+} |
|
12395 |
+function ConfirmConfigExtWindow(messageStr, TitleStr, onOk, onCancel) { |
|
12396 |
+ |
|
12397 |
+ $("#jg_popup_l").empty(); |
|
12398 |
+ $("#jg_popup_b").empty(); |
|
12399 |
+ $("#windowCtrls").empty(); |
|
12400 |
+ $.jeegoopopup.close(); |
|
12401 |
+ |
|
12402 |
+ var html = "<div class=NoSelect>"; |
|
12403 |
+ html += "<div id=windowCtrls><img id=closeImg src=images/3_close.svg title=Close /></div>"; |
|
12404 |
+ html += "<div class=UiText style=\"padding: 10px\" id=ConfirmMessageText>" + messageStr + "</div>"; |
|
12405 |
+ html += "</div>"; |
|
12406 |
+ |
|
12407 |
+ $.jeegoopopup.open({ |
|
12408 |
+ html: html, |
|
12409 |
+ width: '260', |
|
12410 |
+ height: 'auto', |
|
12411 |
+ center: true, |
|
12412 |
+ scrolling: 'no', |
|
12413 |
+ skinClass: 'jg_popup_basic', |
|
12414 |
+ contentClass: 'ConfCloseAccount', |
|
12415 |
+ overlay: true, |
|
12416 |
+ opacity: 50, |
|
12417 |
+ draggable: true, |
|
12418 |
+ resizable: false, |
|
12419 |
+ fadeIn: 0 |
|
12420 |
+ }); |
|
12421 |
+ |
|
12422 |
+ $("#jg_popup_b").append("<div id=ConfCloseAccount><button id=ConfirmOkButton>"+ lang.close_user_account +"</button><button id=ConfirmCancelButton>"+ lang.cancel +"</button></div>"); |
|
12423 |
+ |
|
12424 |
+ $("#ConfirmOkButton").click(function () { |
|
12425 |
+ console.log("Confirm OK clicked"); |
|
12426 |
+ if (onOk) onOk(); |
|
12427 |
+ }); |
|
12428 |
+ $("#ConfirmCancelButton").click(function () { |
|
12429 |
+ console.log("Confirm Cancel clicked"); |
|
12430 |
+ if (onCancel) onCancel(); |
|
12431 |
+ |
|
12432 |
+ $("#windowCtrls").empty(); |
|
12433 |
+ $("#jg_popup_b").empty(); |
|
12434 |
+ $.jeegoopopup.close(); |
|
12435 |
+ ConfigureExtensionWindow(); |
|
12436 |
+ }); |
|
12437 |
+ |
|
12438 |
+ $(window).resize(function() { |
|
12439 |
+ $.jeegoopopup.center(); |
|
12440 |
+ }); |
|
12441 |
+ |
|
12442 |
+ $("#closeImg").click(function() { $("#jg_popup_b").empty(); $("#windowCtrls").empty(); $.jeegoopopup.close(); ConfigureExtensionWindow(); }); |
|
12443 |
+} |
|
12444 |
+function Prompt(messageStr, TitleStr, FieldText, defaultValue, dataType, placeholderText, onOk, onCancel) { |
|
12445 |
+ |
|
12446 |
+ $("#jg_popup_l").empty(); |
|
12447 |
+ $("#jg_popup_b").empty(); |
|
12448 |
+ $("#windowCtrls").empty(); |
|
12449 |
+ $.jeegoopopup.close(); |
|
12450 |
+ |
|
12451 |
+ var html = "<div class=NoSelect>"; |
|
12452 |
+ html += '<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>'; |
|
12453 |
+ html += "<div class=UiText style=\"padding: 10px\" id=PromptMessageText>"; |
|
12454 |
+ html += messageStr; |
|
12455 |
+ html += "<div style=\"margin-top:10px\">" + FieldText + " : </div>"; |
|
12456 |
+ html += "<div style=\"margin-top:5px\"><INPUT id=PromptValueField type=" + dataType + " value=\"" + defaultValue + "\" placeholder=\"" + placeholderText + "\" style=\"width:98%\"></div>" |
|
12457 |
+ html += "</div>"; |
|
12458 |
+ html += "</div>"; |
|
12459 |
+ |
|
12460 |
+ $.jeegoopopup.open({ |
|
12461 |
+ html: html, |
|
12462 |
+ width: '260', |
|
12463 |
+ height: 'auto', |
|
12464 |
+ center: true, |
|
12465 |
+ scrolling: 'no', |
|
12466 |
+ skinClass: 'jg_popup_basic', |
|
12467 |
+ contentClass: 'confirmDelContact', |
|
12468 |
+ overlay: true, |
|
12469 |
+ opacity: 50, |
|
12470 |
+ draggable: true, |
|
12471 |
+ resizable: false, |
|
12472 |
+ fadeIn: 0 |
|
12473 |
+ }); |
|
12474 |
+ |
|
12475 |
+ $("#jg_popup_b").append("<div id=bottomButtons><button id=PromptOkButton style=\"width:80px\">"+ lang.ok +"</button> <button id=PromptCancelButton class=UiButton style=\"width:80px\">"+ lang.cancel +"</button></div>"); |
|
12476 |
+ |
|
12477 |
+ $("#PromptOkButton").click(function () { |
|
12478 |
+ console.log("Prompt OK clicked, with value: " + $("#PromptValueField").val()); |
|
12479 |
+ if (onOk) onOk($("#PromptValueField").val()); |
|
12480 |
+ }); |
|
12481 |
+ |
|
12482 |
+ $("#PromptCancelButton").click(function () { |
|
12483 |
+ console.log("Prompt Cancel clicked"); |
|
12484 |
+ if (onCancel) onCancel(); |
|
12485 |
+ }); |
|
12486 |
+ |
|
12487 |
+ $(window).resize(function() { |
|
12488 |
+ $.jeegoopopup.center(); |
|
12489 |
+ }); |
|
12490 |
+ |
|
12491 |
+ $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12492 |
+ $("#PromptOkButton").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12493 |
+ $("#PromptCancelButton").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12494 |
+ $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); }); |
|
12495 |
+ $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); |
|
12496 |
+} |
|
12497 |
+ |
|
12498 |
+// Device Detection |
|
12499 |
+// ================ |
|
12500 |
+function DetectDevices(){ |
|
12501 |
+ navigator.mediaDevices.enumerateDevices().then(function(deviceInfos){ |
|
12502 |
+ // deviceInfos will not have a populated lable unless to accept the permission |
|
12503 |
+ // during getUserMedia. This normally happens at startup/setup |
|
12504 |
+ // so from then on these devices will be with lables. |
|
12505 |
+ HasVideoDevice = false; |
|
12506 |
+ HasAudioDevice = false; |
|
12507 |
+ HasSpeakerDevice = false; // Safari and Firefox don't have these |
|
12508 |
+ AudioinputDevices = []; |
|
12509 |
+ VideoinputDevices = []; |
|
12510 |
+ SpeakerDevices = []; |
|
12511 |
+ for (var i = 0; i < deviceInfos.length; ++i) { |
|
12512 |
+ if (deviceInfos[i].kind === "audioinput") { |
|
12513 |
+ HasAudioDevice = true; |
|
12514 |
+ AudioinputDevices.push(deviceInfos[i]); |
|
12515 |
+ } |
|
12516 |
+ else if (deviceInfos[i].kind === "audiooutput") { |
|
12517 |
+ HasSpeakerDevice = true; |
|
12518 |
+ SpeakerDevices.push(deviceInfos[i]); |
|
12519 |
+ } |
|
12520 |
+ else if (deviceInfos[i].kind === "videoinput") { |
|
12521 |
+ HasVideoDevice = true; |
|
12522 |
+ VideoinputDevices.push(deviceInfos[i]); |
|
12523 |
+ } |
|
12524 |
+ } |
|
12525 |
+ |
|
12526 |
+ }).catch(function(e){ |
|
12527 |
+ console.error("Error enumerating devices", e); |
|
12528 |
+ }); |
|
12529 |
+} |
|
12530 |
+DetectDevices(); |
|
12531 |
+window.setInterval(function(){ |
|
12532 |
+ DetectDevices(); |
|
12533 |
+}, 10000); |
|
12534 |
+ |
|
12535 |
+// STATUS_NULL: 0 |
|
12536 |
+// STATUS_INVITE_SENT: 1 |
|
12537 |
+// STATUS_1XX_RECEIVED: 2 |
|
12538 |
+// STATUS_INVITE_RECEIVED: 3 |
|
12539 |
+// STATUS_WAITING_FOR_ANSWER: 4 |
|
12540 |
+// STATUS_ANSWERED: 5 |
|
12541 |
+// STATUS_WAITING_FOR_PRACK: 6 |
|
12542 |
+// STATUS_WAITING_FOR_ACK: 7 |
|
12543 |
+// STATUS_CANCELED: 8 |
|
12544 |
+// STATUS_TERMINATED: 9 |
|
12545 |
+// STATUS_ANSWERED_WAITING_FOR_PRACK: 10 |
|
12546 |
+// STATUS_EARLY_MEDIA: 11 |
|
12547 |
+// STATUS_CONFIRMED: 12 |
|
12548 |
+ |
|
12549 |
+// ======================================= |
|
12550 |
+// End Of File |
0 | 12551 |
new file mode 100644 |
... | ... |
@@ -0,0 +1 @@ |
1 |
+var enabledExtendedServices=!1,enabledGroupServices=!1;const availableLang=["ja","zh-hans","zh","ru","tr","nl"];var wssServer=getDbItem("wssServer",null),profileUserID=getDbItem("profileUserID",null),profileUser=getDbItem("profileUser",null),profileName=getDbItem("profileName",null),WebSocketPort=getDbItem("WebSocketPort",null),ServerPath=getDbItem("ServerPath",null),SipUsername=getDbItem("SipUsername",null),SipPassword=getDbItem("SipPassword",null),StunServer=getDbItem("StunServer",""),TransportConnectionTimeout=parseInt(getDbItem("TransportConnectionTimeout",15)),TransportReconnectionAttempts=parseInt(getDbItem("TransportReconnectionAttempts",99)),TransportReconnectionTimeout=parseInt(getDbItem("TransportReconnectionTimeout",15)),userAgentStr=getDbItem("UserAgentStr","Roundpin (SipJS - 0.11.6)"),hostingPrefex=getDbItem("HostingPrefex",""),RegisterExpires=parseInt(getDbItem("RegisterExpires",300)),WssInTransport="1"==getDbItem("WssInTransport","1"),IpInContact="1"==getDbItem("IpInContact","1"),IceStunCheckTimeout=parseInt(getDbItem("IceStunCheckTimeout",500)),AutoAnswerEnabled="1"==getDbItem("AutoAnswerEnabled","0"),DoNotDisturbEnabled="1"==getDbItem("DoNotDisturbEnabled","0"),CallWaitingEnabled="1"==getDbItem("CallWaitingEnabled","1"),RecordAllCalls="1"==getDbItem("RecordAllCalls","0"),StartVideoFullScreen="0"==getDbItem("StartVideoFullScreen","1"),AutoGainControl="1"==getDbItem("AutoGainControl","1"),EchoCancellation="1"==getDbItem("EchoCancellation","1"),NoiseSuppression="1"==getDbItem("NoiseSuppression","1"),MirrorVideo=getDbItem("VideoOrientation","rotateY(180deg)"),maxFrameRate=getDbItem("FrameRate",""),videoHeight=getDbItem("VideoHeight",""),videoAspectRatio=getDbItem("AspectRatio",""),NotificationsActive="1"==getDbItem("Notifications","0"),StreamBuffer=parseInt(getDbItem("StreamBuffer",50)),PosterJpegQuality=parseFloat(getDbItem("PosterJpegQuality",.6)),VideoResampleSize=getDbItem("VideoResampleSize","HD"),RecordingVideoSize=getDbItem("RecordingVideoSize","HD"),RecordingVideoFps=parseInt(getDbItem("RecordingVideoFps",12)),RecordingLayout=getDbItem("RecordingLayout","them-pnp"),DidLength=parseInt(getDbItem("DidLength",6)),MaxDidLength=parseInt(getDbItem("maximumNumberLength",16)),DisplayDateFormat=getDbItem("DateFormat","YYYY-MM-DD"),DisplayTimeFormat=getDbItem("TimeFormat","h:mm:ss A"),Language=getDbItem("Language","auto"),EnableTextMessaging="1"==getDbItem("EnableTextMessaging","1"),DisableFreeDial="1"==getDbItem("DisableFreeDial","0"),DisableBuddies="1"==getDbItem("DisableBuddies","0"),EnableTransfer="1"==getDbItem("EnableTransfer","1"),EnableConference="1"==getDbItem("EnableConference","1"),AutoAnswerPolicy=getDbItem("AutoAnswerPolicy","allow"),DoNotDisturbPolicy=getDbItem("DoNotDisturbPolicy","allow"),CallWaitingPolicy=getDbItem("CallWaitingPolicy","allow"),CallRecordingPolicy=getDbItem("CallRecordingPolicy","allow"),EnableAccountSettings="1"==getDbItem("EnableAccountSettings","1"),EnableAudioVideoSettings="1"==getDbItem("EnableAudioVideoSettings","1"),EnableAppearanceSettings="1"==getDbItem("EnableAppearanceSettings","1"),EnableChangeUserPasswordSettings="1"==getDbItem("EnableChangeUserPasswordSettings","1"),EnableChangeUserEmailSettings="1"==getDbItem("EnableChangeUserEmailSettings","1"),EnableCloseUserAccount="1"==getDbItem("EnableCloseUserAccount","1"),EnableAlphanumericDial="1"==getDbItem("EnableAlphanumericDial","1"),EnableVideoCalling="1"==getDbItem("EnableVideoCalling","1"),winVideoConf=null,winVideoConfCheck=0,localDB=window.localStorage,userAgent=null,voicemailSubs=null,BlfSubs=[],CanvasCollection=[],Buddies=[],isReRegister=!1,dhtmlxPopup=null,selectedBuddy=null,selectedLine=null,alertObj=null,confirmObj=null,promptObj=null,windowsCollection=null,messagingCollection=null,HasVideoDevice=!1,HasAudioDevice=!1,HasSpeakerDevice=!1,AudioinputDevices=[],VideoinputDevices=[],SpeakerDevices=[],Lines=[],lang={},audioBlobs={},newLineNumber=0,videoAudioCheck=0,RCLoginCheck=0,decSipPass="",currentChatPrivKey="",sendFileCheck=0,upFileName="",sendFileChatErr="",pubKeyCheck=0,splitMessage={};function uID(){return Date.now()+Math.floor(1e4*Math.random()).toString(16).toUpperCase()}function utcDateNow(){return moment().utc().format("YYYY-MM-DD HH:mm:ss UTC")}function getDbItem(e,t){var i=window.localStorage;return null!=i.getItem(e)?i.getItem(e):t}function getAudioSrcID(){var e=localDB.getItem("AudioSrcId");return null!=e?e:"default"}function getAudioOutputID(){var e=localDB.getItem("AudioOutputId");return null!=e?e:"default"}function getVideoSrcID(){var e=localDB.getItem("VideoSrcId");return null!=e?e:"default"}function getRingerOutputID(){var e=localDB.getItem("RingOutputId");return null!=e?e:"default"}function formatDuration(e){var t,i=Math.floor(parseFloat(e));return i<0?i:i>=0&&i<60?i+" "+(1!=i?lang.seconds_plural:lang.second_single):i>=60&&i<3600?(t=moment.duration(i,"seconds")).minutes()+" "+(1!=t.minutes()?lang.minutes_plural:lang.minute_single)+" "+t.seconds()+" "+(1!=t.seconds()?lang.seconds_plural:lang.second_single):i>=3600&&i<86400?(t=moment.duration(i,"seconds")).hours()+" "+(1!=t.hours()?lang.hours_plural:lang.hour_single)+" "+t.minutes()+" "+(1!=t.minutes()?lang.minutes_plural:lang.minute_single)+" "+t.seconds()+" "+(1!=t.seconds()?lang.seconds_plural:lang.second_single):void 0}function formatShortDuration(e){var t,i=Math.floor(parseFloat(e));return i<0?i:i>=0&&i<60?"00:"+(i>9?i:"0"+i):i>=60&&i<3600?((t=moment.duration(i,"seconds")).minutes()>9?t.minutes():"0"+t.minutes())+":"+(t.seconds()>9?t.seconds():"0"+t.seconds()):i>=3600&&i<86400?((t=moment.duration(i,"seconds")).hours()>9?t.hours():"0"+t.hours())+":"+(t.minutes()>9?t.minutes():"0"+t.minutes())+":"+(t.seconds()>9?t.seconds():"0"+t.seconds()):void 0}function formatBytes(e,t){if(0===e)return"0 "+lang.bytes;var i=t&&t>=0?t:2,n=[lang.bytes,lang.kb,lang.mb,lang.gb,lang.tb,lang.pb,lang.eb,lang.zb,lang.yb],a=Math.floor(Math.log(e)/Math.log(1024));return parseFloat((e/Math.pow(1024,a)).toFixed(i))+" "+n[a]}function UserLocale(){var e=window.navigator.userLanguage||window.navigator.language;return langtag=e.split("-"),1==langtag.length?"":2==langtag.length||langtag.length>=3?langtag[1].toLowerCase():void 0}function GetAlternateLanguage(){var e=window.navigator.userLanguage||window.navigator.language;if("auto"!=Language&&(e=Language),"en"==(e=e.toLowerCase())||0==e.indexOf("en-"))return"";for(l=0;l<availableLang.length;l++)if(0==e.indexOf(availableLang[l].toLowerCase()))return console.log("Alternate Language detected: ",e),moment.locale(e),availableLang[l].toLowerCase();return""}function getFilter(e,t){return-1!=e.indexOf(",",e.indexOf(t+": ")+t.length+2)?e.substring(e.indexOf(t+": ")+t.length+2,e.indexOf(",",e.indexOf(t+": ")+t.length+2)):e.substring(e.indexOf(t+": ")+t.length+2)}function base64toBlob(e,t){e.indexOf(!0)&&(e=e.split(",")[1]);for(var i=atob(e),n=Math.ceil(i.length/1024),a=new Array(n),o=0;o<n;++o){for(var l=1024*o,s=Math.min(l+1024,i.length),r=new Array(s-l),d=l,c=0;d<s;++c,++d)r[c]=i[d].charCodeAt(0);a[o]=new Uint8Array(r)}return new Blob(a,{type:t})}function MakeDataArray(e,t){for(var i=new Array(t),n=0;n<i.length;n++)i[n]=e;return i}function saveConfToSqldb(){wssServer=$("#Configure_Account_wssServer").val(),WebSocketPort=parseInt($("#Configure_Account_WebSocketPort").val()),ServerPath=$("#Configure_Account_ServerPath").val(),profileName=$("#Configure_Account_profileName").val(),SipUsername=$("#Configure_Account_SipUsername").val(),SipPassword=$("#Configure_Account_SipPassword").val();var e=$("#Configure_Account_StunServer").val(),t=$("#playbackSrc").val(),i=$("#previewVideoSrc").val(),n=$("input[name=Settings_Quality]:checked").val(),a=parseInt($("input[name=Settings_FrameRate]:checked").val()),o=$("input[name=Settings_AspectRatio]:checked").val(),l=$("input[name=Settings_Oriteation]:checked").val(),s=$("#microphoneSrc").val(),r=$("#Settings_AutoGainControl").is(":checked")?"1":"0",d=$("#Settings_EchoCancellation").is(":checked")?"1":"0",c=$("#Settings_NoiseSuppression").is(":checked")?"1":"0",u=$("#ringDevice").val(),p=$("#Video_Conf_Extension").val(),g=$("#Video_Conf_Window_Width").val(),m=void 0===getDbItem("profilePicture","")?"":getDbItem("profilePicture",""),f=$("#Settings_Notifications").is(":checked")?1:0,v=$("#emailIntegration").is(":checked")?1:0,h=$("#RoundcubeDomain").val(),b=$("#rcBasicAuthUser").val(),y=$("#rcBasicAuthPass").val(),w=$("#RoundcubeUser").val(),S=$("#RoundcubePass").val();""!=userName?""!=wssServer&&""!=WebSocketPort&&""!=ServerPath&&""!=SipUsername&&""!=SipPassword?$.ajax({type:"POST",url:"save-update-settings.php",dataType:"JSON",data:{username:userName,wss_server:wssServer,web_socket_port:WebSocketPort,server_path:ServerPath,profile_name:profileName,sip_username:SipUsername,sip_password:SipPassword,stun_server:e,audio_output_id:t,video_src_id:i,video_height:n,frame_rate:a,aspect_ratio:o,video_orientation:l,audio_src_id:s,auto_gain_control:r,echo_cancellation:d,noise_suppression:c,ring_output_id:u,video_conf_extension:p,video_conf_window_width:g,profile_picture:m,notifications:f,use_roundcube:v,rcdomain:h,rcbasicauthuser:b,rcbasicauthpass:y,rcuser:w,rcpassword:S,s_ajax_call:validateSToken},success:function(e){window.location.reload()},error:function(e){alert("An error occurred while attempting to save the account configuration data!")}}):alert("Fields: 'WebSocket Domain', 'WebSocket Port', 'WebSocket Path', 'SIP Username' and 'SIP Password' are required ! Please fill in all these fields !"):alert("An error occurred while attempting to save the data!")}function getConfFromSqldb(){$.ajax({type:"POST",url:"get-settings.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(e){if(null==e.wss_server||null==e.web_socket_port||null==e.server_path||null==e.sip_username||null==e.sip_password)ConfigureExtensionWindow();else{if(localStorage.getItem("firstReLoad")||(localStorage.firstReLoad=!0,window.setTimeout((function(){window.location.reload()}),200)),null==e.stun_server||void 0===e.stun_server)var t="";else t=e.stun_server;localDB.setItem("profileUserID",uID()),localDB.setItem("userrole",e.userrole),localDB.setItem("wssServer",e.wss_server),localDB.setItem("WebSocketPort",e.web_socket_port),localDB.setItem("ServerPath",e.server_path),localDB.setItem("profileUser",e.sip_username),localDB.setItem("profileName",e.profile_name),localDB.setItem("SipUsername",e.sip_username),localDB.setItem("SipPassword",e.sip_password),localDB.setItem("StunServer",t),localDB.setItem("AudioOutputId",e.audio_output_id),localDB.setItem("VideoSrcId",e.video_src_id),localDB.setItem("VideoHeight",e.video_height),localDB.setItem("FrameRate",e.frame_rate),localDB.setItem("AspectRatio",e.aspect_ratio),localDB.setItem("VideoOrientation",e.video_orientation),localDB.setItem("AudioSrcId",e.audio_src_id),localDB.setItem("AutoGainControl",e.auto_gain_control),localDB.setItem("EchoCancellation",e.echo_cancellation),localDB.setItem("NoiseSuppression",e.noise_suppression),localDB.setItem("RingOutputId",e.ring_output_id),localDB.setItem("VidConfExtension",e.video_conf_extension),localDB.setItem("VidConfWindowWidth",e.video_conf_window_width),localDB.setItem("profilePicture",e.profile_picture),localDB.setItem("Notifications",e.notifications),localDB.setItem("useRoundcube",e.use_roundcube),localDB.setItem("rcDomain",""!=e.rcdomain&&null!=e.rcdomain&&void 0!==e.rcdomain?e.rcdomain:""),localDB.setItem("rcBasicAuthUser",e.rcbasicauthuser),localDB.setItem("rcBasicAuthPass",e.rcbasicauthpass),localDB.setItem("RoundcubeUser",e.rcuser),localDB.setItem("RoundcubePass",e.rcpassword),Register()}},error:function(e){alert("An error occurred while attempting to retrieve account configuration data from the database!")}})}function saveContactToSQLDB(e){0!=e.length?$.ajax({type:"POST",url:"save-contact.php",dataType:"JSON",data:{username:userName,contact_name:e[0],contact_desc:e[1],extension_number:e[2],contact_mobile:e[3],contact_num1:e[4],contact_num2:e[5],contact_email:e[6],s_ajax_call:validateSToken},success:function(e){"success"!=e.result&&alert(e.result)},error:function(e){alert("An error occurred while attempting to save the contact to the database!")}}):alert("An error occurred while attempting to save the data!")}function updateContactToSQLDB(e){0!=e.length?""!=e[7]&&null!=e[7]&&void 0!==e[7]?$.ajax({type:"POST",url:"update-contact.php",dataType:"JSON",data:{contact_name:e[0],contact_desc:e[1],extension_number:e[2],contact_mobile:e[3],contact_num1:e[4],contact_num2:e[5],contact_email:e[6],contactDBID:e[7],s_ajax_call:validateSToken},success:function(e){"success"!=e.result&&alert(e.result)},error:function(e){alert("An error occurred while attempting to save the data!")}}):alert("Error while attempting to retrieve contact data from the database!"):alert("An error occurred while attempting to save the data!")}function saveContactPicToSQLDB(e){0!=e.length?$.ajax({type:"POST",url:"save-update-contact-picture.php",dataType:"JSON",data:{username:userName,contact_name:e[0],profile_picture_c:e[1],s_ajax_call:validateSToken},success:function(e){},error:function(e){alert("An error occurred while attempting to save contact picture!")}}):alert("An error occurred while attempting to save contact picture!")}function getContactsFromSQLDB(){$.ajax({type:"POST",url:"get-contacts.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(e){var t=InitUserBuddies();$.each(e.contactsinfo,(function(i,n){var a=uID(),o=utcDateNow();""==e.contactsinfo[i].extension_number||null==e.contactsinfo[i].extension_number?(t.DataCollection.push({Type:"contact",LastActivity:o,ExtensionNumber:"",MobileNumber:e.contactsinfo[i].contact_mobile,ContactNumber1:e.contactsinfo[i].contact_num1,ContactNumber2:e.contactsinfo[i].contact_num2,uID:null,cID:a,gID:null,DisplayName:e.contactsinfo[i].contact_name,Position:"",Description:e.contactsinfo[i].contact_desc,Email:e.contactsinfo[i].contact_email,MemberCount:0}),""!=e.contactsinfo[i].profile_picture_c&&null!=e.contactsinfo[i].profile_picture_c&&localDB.setItem("img-"+a+"-contact",e.contactsinfo[i].profile_picture_c),AddBuddy(new Buddy("contact",a,e.contactsinfo[i].contact_name,"",e.contactsinfo[i].contact_mobile,e.contactsinfo[i].contact_num1,e.contactsinfo[i].contact_num2,o,e.contactsinfo[i].contact_desc,e.contactsinfo[i].contact_email),!0,!1,!1)):(t.DataCollection.push({Type:"extension",LastActivity:o,ExtensionNumber:e.contactsinfo[i].extension_number,MobileNumber:e.contactsinfo[i].contact_mobile,ContactNumber1:e.contactsinfo[i].contact_num1,ContactNumber2:e.contactsinfo[i].contact_num2,uID:a,cID:null,gID:null,DisplayName:e.contactsinfo[i].contact_name,Position:e.contactsinfo[i].contact_desc,Description:"",Email:e.contactsinfo[i].contact_email,MemberCount:0}),""!=e.contactsinfo[i].profile_picture_c&&null!=e.contactsinfo[i].profile_picture_c&&localDB.setItem("img-"+a+"-extension",e.contactsinfo[i].profile_picture_c),AddBuddy(new Buddy("extension",a,e.contactsinfo[i].contact_name,e.contactsinfo[i].extension_number,e.contactsinfo[i].contact_mobile,e.contactsinfo[i].contact_num1,e.contactsinfo[i].contact_num2,o,e.contactsinfo[i].contact_desc,e.contactsinfo[i].contact_email),!0,!1,!0))})),t.TotalRows=t.DataCollection.length,localDB.setItem(profileUserID+"-Buddies",JSON.stringify(t)),UpdateUI(),PopulateBuddyList()},error:function(e){alert("An error occurred while attempting to retrieve contacts data from the database!")}})}function getExternalUserConfFromSqldb(){$.ajax({type:"POST",url:"get-external-users-conf.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(e){if(JSON.stringify(e).length>0){localDB.setItem("externalUserConfElem",e.length);for(var t=0;t<e.length;t++)localDB.setItem("extUserExtension-"+t,e[t].exten_for_external),localDB.setItem("extUserExtensionPass-"+t,e[t].exten_for_ext_pass),localDB.setItem("confAccessLink-"+t,e[t].conf_access_link)}},error:function(e){alert("An error occurred while attempting to retrieve external users configuration data from the database!")}})}function checkExternalLinks(){confirm("Links that can allow external users to access the video conferences are stored in the database. If you don't need them anymore, it's recommended to remove them in order to prevent unwanted access to your conferences. Press OK to remove all the links for external access associated with your username from the database and then exit Roundpin, or press Cancel to leave the links in the database and just exit.")?$.ajax({type:"POST",url:"remove-links-for-external-access.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(e){alert("All the links for external access to conferences associated with your username have been successfully removed from the database!"),Unregister(),console.log("Signing Out ..."),localStorage.clear(),null!=winVideoConf&&winVideoConf.close(),window.open("https://"+window.location.host+"/logout.php","_self")},error:function(e){alert("An error occurred while trying to remove the data from the database!"),Unregister(),console.log("Signing Out ..."),localStorage.clear(),null!=winVideoConf&&winVideoConf.close(),window.open("https://"+window.location.host+"/logout.php","_self")}}):(Unregister(),console.log("Signing Out ..."),localStorage.clear(),null!=winVideoConf&&winVideoConf.close(),window.open("https://"+window.location.host+"/logout.php","_self"))}function deleteBuddyFromSqldb(e){$.ajax({type:"POST",url:"remove-contact.php",dataType:"JSON",data:{username:userName,contact_name:e,s_ajax_call:validateSToken},success:function(e){},error:function(e){alert("An error occurred while attempting to remove the contact from the database!")}})}function saveNewUserPassword(){var e=$("#Current_User_Password").val(),t=$("#New_User_Password").val(),i=$("#Repeat_New_User_Password").val();""!=e&&""!=t&&""!=i?/^((?=.*\d)(?=.*[a-z])(?=.*\W).{10,})$/.test(t)?i==t?$.ajax({type:"POST",url:"save-new-user-password.php",dataType:"JSON",data:{username:userName,current_password:e,new_password:t,s_ajax_call:validateSToken},success:function(e){alert(e)},error:function(e){alert("An error occurred while attempting to change the user password!")}}):alert("The passwords entered in the new password fields don't match!"):alert("The new password does not meet the requirements (to be at least 10 characters long, to contain at least one letter, at least one digit and at least one special character). Please choose a different password ! "):alert("Please fill in all the fields!")}function saveNewUserEmail(){var e=$("#Current_User_Email").val(),t=$("#New_User_Email").val(),i=$("#Repeat_New_User_Email").val();""!=e&&""!=t&&""!=i?/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(t)?i==t?$.ajax({type:"POST",url:"save-new-user-email.php",dataType:"JSON",data:{username:userName,current_email:e,new_email:t,s_ajax_call:validateSToken},success:function(e){alert(e)},error:function(e){alert("An error occurred while attempting to change the user email address!")}}):alert("The email addresses entered in the new email fields don't match!"):alert("The new email address is not a valid email address. Please enter a valid email address!"):alert("Please fill in all the fields!")}function closeUserAccount(){closeVideoAudio(),ConfirmConfigExtWindow(lang.confirm_close_account,lang.close_roundpin_user_account,(function(){$.ajax({type:"POST",url:"close-user-account.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(e){alert(e),SignOut()},error:function(e){alert("An error occurred while attempting to close your user account!")}})}))}function LaunchVideoConference(){0==winVideoConfCheck?(winVideoConf=window.open("https://"+window.location.host+"/videoconference/index.php"),winVideoConfCheck=1):alert('The video conference has been launched. If you want to launch it again refresh the page, then click "Launch Video Conference".')}function generateChatRSAKeys(e){var t=new JSEncrypt({default_key_size:1024});t.getKey();var i=t.getPublicKey();currentChatPrivKey=t.getPrivateKey(),$.ajax({type:"POST",url:"save-text-chat-pub-key.php",dataType:"JSON",data:{currentextension:e,currentchatpubkey:i,s_ajax_call:validateSToken},success:function(){},error:function(){alert("An error occurred while trying to save the new text chat public key!")}})}function removeTextChatUploads(e){$.ajax({async:!1,global:!1,type:"POST",url:"text-chat-remove-uploaded-files.php",dataType:"JSON",data:{sipusername:e,s_ajax_call:validateSToken},success:function(e){"success"!=e.note&&alert("An error occurred while trying to remove the text chat 'uploads' directory!")},error:function(e){alert("An error occurred while attempting to remove the text chat 'uploads' directory!")}})}function closeVideoConfTab(){winVideoConf&&winVideoConf.close()}function ShowEmailWindow(){if(1==getDbItem("useRoundcube","")){$("#roundcubeFrame").remove(),$("#rightContent").show(),$(".streamSelected").each((function(){$(this).css("display","none")})),$("#rightContent").append('<iframe id="roundcubeFrame" name="displayFrame"></iframe>');var e="",t="",i="",n="",a="";if($.ajax({async:!1,global:!1,type:"POST",url:"get-email-info.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(o){e=o.rcdomain,t=encodeURIComponent(o.rcbasicauthuser),i=encodeURIComponent(o.rcbasicauthpass),n=o.rcuser,a=o.rcpassword},error:function(e){alert("An error occurred while trying to retrieve data from the database!")}}),""!=t&&""!=i)var o="https://"+t+":"+i+"@"+e+"/";else o="https://"+e+"/";var l='<form id="rcForm" method="POST" action="'+o+'" target="displayFrame">';l+='<input type="hidden" name="_action" value="login" />',l+='<input type="hidden" name="_task" value="login" />',l+='<input type="hidden" name="_autologin" value="1" />',l+='<input name="_user" value="'+n+'" type="text" />',l+='<input name="_pass" value="'+a+'" type="password" />',l+='<input id="submitButton" type="submit" value="Login" />',l+="</form>",$("#roundcubeFrame").append(l),0==RCLoginCheck?($("#submitButton").click(),RCLoginCheck=1):$("#roundcubeFrame").attr("src",o)}else alert("Email Integration is not enabled ! You can enable Roundcube email integration by clicking on the 'Settings' wheel in the user profile section from below > 'Settings' > 'Email Integration' > 'Enable Roundcube email integration'")}function CollapseLeftPanel(){$(window).width()>=920&&($("#leftContent").hasClass("shrinkLeftContent")?($("#leftContent").removeClass("shrinkLeftContent"),$("#rightContent").removeClass("widenRightContent"),$("#aboutImg").css("margin-right","-3px")):($("#leftContent").addClass("shrinkLeftContent"),$("#rightContent").addClass("widenRightContent"),$("#aboutImg").css("margin-right","3px")))}function ShowAboutWindow(){$.jeegoopopup.close();var e="<div>";e+='<div id="windowCtrls"><img id="minimizeImg" src="images/1_minimize.svg" title="Restore" /><img id="maximizeImg" src="images/2_maximize.svg" title="Maximize" /><img id="closeImg" src="images/3_close.svg" title="Close" /></div>',e+='<div class="UiWindowField scroller">',e+='<div><img id="AboutLogoImg" src="images/login-logo.svg"/></div>',e+='<div id="aboutPopup">'+lang.about_text+"</div>",e+="</div></div>",$.jeegoopopup.open({title:"About Roundpin",html:e,width:"640",height:"500",center:!0,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append('<button id="ok_button">'+lang.ok+"</button>");var t=$(window).width()-12,i=$(window).height()-88;t<656||i<500?($.jeegoopopup.width(t).height(i),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show()),$(window).resize((function(){t=$(window).width()-12,i=$(window).height()-88,$.jeegoopopup.center(),t<656||i<500?($.jeegoopopup.width(t).height(i),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show())})),$("#minimizeImg").click((function(){$.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#maximizeImg").show(),$("#minimizeImg").hide()})),$("#maximizeImg").click((function(){$.jeegoopopup.width(t).height(i),$.jeegoopopup.center(),$("#minimizeImg").show(),$("#maximizeImg").hide()})),$("#closeImg").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#ok_button").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($.jeegoopopup.close(),$("#jg_popup_b").empty())}))}function incomingCallNote(){new Notification(lang.incomming_call,{icon:"../images/notification-logo.svg",body:"New incoming call !!!"}).onclick=function(e){},document.hasFocus()||setTimeout(incomingCallNote,8e3)}function changePageTitle(){"Roundpin"==$(document).attr("title")?$(document).prop("title","New call !!!"):$(document).prop("title","Roundpin"),document.hasFocus()?$(document).prop("title","Roundpin"):setTimeout(changePageTitle,460)}function UpdateUI(){$(window).outerWidth()<920?null==selectedBuddy&null==selectedLine?($("#rightContent").hide(),$("#leftContent").css("width","100%"),$("#leftContent").show()):($("#rightContent").css("margin-left","0px"),$("#rightContent").show(),$("#leftContent").hide(),null!=selectedBuddy&&updateScroll(selectedBuddy.identity)):null==selectedBuddy&null==selectedLine?($("#leftContent").css("width","320px"),$("#rightContent").css("margin-left","0px"),$("#leftContent").show(),$("#rightContent").hide()):($("#leftContent").css("width","320px"),$("#rightContent").css("margin-left","320px"),$("#leftContent").show(),$("#rightContent").show(),null!=selectedBuddy&&updateScroll(selectedBuddy.identity));for(var e=0;e<Lines.length;e++)updateLineScroll(Lines[e].LineNumber)}function AddSomeoneWindow(e){$("#userMenu").hide(),$.jeegoopopup.close();var t="<div id='AddNewContact'>";t+="<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>",t+="<div class='UiWindowField scroller'>",t+="<div class=UiText>"+lang.display_name+":</div>",t+="<div><input id=AddSomeone_Name class=UiInputText type=text placeholder='"+lang.eg_display_name+"'></div>",t+="<div class=UiText>"+lang.title_description+":</div>",t+="<div><input id=AddSomeone_Desc class=UiInputText type=text placeholder='"+lang.eg_general_manager+"'></div>",t+="<div class=UiText>"+lang.internal_subscribe_extension+":</div>",e&&e.length>1&&e.length<DidLength&&"*"!=e.substring(0,1)?t+="<div><input id=AddSomeone_Exten class=UiInputText type=text value="+e+" placeholder='"+lang.eg_internal_subscribe_extension+"'></div>":t+="<div><input id=AddSomeone_Exten class=UiInputText type=text placeholder='"+lang.eg_internal_subscribe_extension+"'></div>",t+="<div class=UiText>"+lang.mobile_number+":</div>",t+="<div><input id=AddSomeone_Mobile class=UiInputText type=text placeholder='"+lang.eg_mobile_number+"'></div>",t+="<div class=UiText>"+lang.contact_number_1+":</div>",e&&e.length>1?t+="<div><input id=AddSomeone_Num1 class=UiInputText type=text value="+e+" placeholder='"+lang.eg_contact_number_1+"'></div>":t+="<div><input id=AddSomeone_Num1 class=UiInputText type=text placeholder='"+lang.eg_contact_number_1+"'></div>",t+="<div class=UiText>"+lang.contact_number_2+":</div>",t+="<div><input id=AddSomeone_Num2 class=UiInputText type=text placeholder='"+lang.eg_contact_number_2+"'></div>",t+="<div class=UiText>"+lang.email+":</div>",t+="<div><input id=AddSomeone_Email class=UiInputText type=text placeholder='"+lang.eg_email+"'></div>",t+="</div></div>",$.jeegoopopup.open({title:"Add Contact",html:t,width:"640",height:"500",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"addContactPopup",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append("<div id=bottomButtons><button id=save_button>Save</button><button id=cancel_button>Cancel</button></div>"),$("#save_button").click((function(){var e=$("#AddSomeone_Name").val();if(null!=e&&""!==e.trim())if(/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(e)){var t=$("#AddSomeone_Desc").val();if(null!=t&&""!==t.trim())if(/^[A-Za-z0-9\s\-\.\'\"\[\]\(\)\{\}\_\!\?\~\@\%\^\&\*\+\>\<\;\:\=]+$/.test(t))var i=t;else{i="";alert("The title/description that you entered is not valid!")}else i="";var n=$("#AddSomeone_Exten").val();if(null!=n&&""!==n.trim())if(/^[a-zA-Z0-9\*\#]+$/.test(n))var a=n;else{a="";alert("The extension that you entered in the 'Extension (Internal)' field is not a valid extension!")}else a="";var o=$("#AddSomeone_Mobile").val();if(null!=o&&""!==o.trim())if(/^[0-9\s\+\#]+$/.test(o))var l=o;else{l="";alert("The phone number that you entered in the 'Mobile Number' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs.")}else l="";var s=$("#AddSomeone_Num1").val();if(null!=s&&""!==s.trim())if(/^[0-9\s\+\#]+$/.test(s))var r=s;else{r="";alert("The phone number that you entered in the 'Contact Number 1' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs.")}else r="";var d=$("#AddSomeone_Num2").val();if(null!=d&&""!==d.trim())if(/^[0-9\s\+\#]+$/.test(d))var c=d;else{c="";alert("The phone number that you entered in the 'Contact Number 2' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs.")}else c="";var u=$("#AddSomeone_Email").val();if(null!=u&&""!==u.trim())if(/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(u))var p=u;else{p="";alert("The email that you entered is not a valid email address!")}else p="";var g=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));if(null==g&&(g=InitUserBuddies()),""==a){var m=uID(),f=utcDateNow();g.DataCollection.push({Type:"contact",LastActivity:f,ExtensionNumber:"",MobileNumber:l,ContactNumber1:r,ContactNumber2:c,uID:null,cID:m,gID:null,DisplayName:e,Position:"",Description:i,Email:p,MemberCount:0});saveContactToSQLDB([e,i,"",l,r,c,p]),AddBuddy(new Buddy("contact",m,e,"",l,r,c,f,i,p),!1,!1,!1)}else{m=uID(),f=utcDateNow();g.DataCollection.push({Type:"extension",LastActivity:f,ExtensionNumber:a,MobileNumber:l,ContactNumber1:r,ContactNumber2:c,uID:m,cID:null,gID:null,DisplayName:e,Position:i,Description:"",Email:p,MemberCount:0});saveContactToSQLDB([e,i,a,l,r,c,p]),AddBuddy(new Buddy("extension",m,e,a,l,r,c,f,i,p),!1,!1,!0)}g.TotalRows=g.DataCollection.length,localDB.setItem(profileUserID+"-Buddies",JSON.stringify(g)),UpdateBuddyList(),$.jeegoopopup.close(),$("#jg_popup_b").empty()}else alert("The display name that you entered is not a valid display name!");else alert("'Display Name' cannot be empty!")}));var i=$(window).width()-12,n=$(window).height()-110;i<656||n<500?($.jeegoopopup.width(i).height(n),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show()),$(window).resize((function(){i=$(window).width()-16,n=$(window).height()-110,$.jeegoopopup.center(),i<656||n<500?($.jeegoopopup.width(i).height(n),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show())})),$("#minimizeImg").click((function(){$.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#maximizeImg").show(),$("#minimizeImg").hide()})),$("#maximizeImg").click((function(){$.jeegoopopup.width(i).height(n),$.jeegoopopup.center(),$("#minimizeImg").show(),$("#maximizeImg").hide()})),$("#closeImg").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#cancel_button").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($.jeegoopopup.close(),$("#jg_popup_b").empty())}))}function CreateGroupWindow(){}function closeVideoAudio(){var e=$("#local-video-preview").get(0);try{e.srcObject.getTracks().forEach((function(e){e.stop()})),e.srcObject=null}catch(e){}try{window.SettingsMicrophoneStream.getTracks().forEach((function(e){e.stop()}))}catch(e){}window.SettingsMicrophoneStream=null;try{window.SettingsMicrophoneSoundMeter.stop()}catch(e){}window.SettingsMicrophoneSoundMeter=null;try{window.SettingsOutputAudio.pause()}catch(e){}window.SettingsOutputAudio=null;try{window.SettingsOutputStream.getTracks().forEach((function(e){e.stop()}))}catch(e){}window.SettingsOutputStream=null;try{window.SettingsOutputStreamMeter.stop()}catch(e){}return window.SettingsOutputStreamMeter=null,!0}function ConfigureExtensionWindow(){$("#settingsCMenu").hide(),$.jeegoopopup.close();var e='<div id="mainConfWindow">';e+="<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>",e+='<div id="mainRightConf">',e+='<div id="rightMainConfWindow">',e+='<div id="AccountHtml" class="settingsSubSection" style="display:block;">',e+="<div class=UiText>"+lang.asterisk_server_address+": *</div>",e+="<div><input id=Configure_Account_wssServer class=UiInputText type=text placeholder='"+lang.eg_asterisk_server_address+"' value='"+getDbItem("wssServer","")+"'></div>",e+="<div class=UiText>"+lang.websocket_port+": *</div>",e+="<div><input id=Configure_Account_WebSocketPort class=UiInputText type=text placeholder='"+lang.eg_websocket_port+"' value='"+getDbItem("WebSocketPort","")+"'></div>",e+="<div class=UiText>"+lang.websocket_path+": *</div>",e+="<div><input id=Configure_Account_ServerPath class=UiInputText type=text placeholder='"+lang.eg_websocket_path+"' value='"+getDbItem("ServerPath","")+"'></div>",e+="<div class=UiText>"+lang.display_name+": *</div>";var t='value="'+getDbItem("profileName","").replace("'","'")+'"';if(e+="<div><input id=Configure_Account_profileName class=UiInputText type=text placeholder='"+lang.eg_display_name+"' "+t+"></div>",e+="<div class=UiText>"+lang.sip_username+": *</div>",e+="<div><input id=Configure_Account_SipUsername class=UiInputText type=text placeholder='"+lang.eg_sip_username+"' value='"+getDbItem("SipUsername","")+"'></div>",e+="<div class=UiText>"+lang.sip_password+": *</div>",e+="<div><input id=Configure_Account_SipPassword class=UiInputText type=password placeholder='"+lang.eg_sip_password+"' value='"+getDbItem("SipPassword","")+"'></div>",e+="<div class=UiText>"+lang.stun_server+":</div>",e+="<div><input id=Configure_Account_StunServer class=UiInputText type=text placeholder='Eg: 123.123.123.123:8443' value='"+getDbItem("StunServer","")+"'></div>",e+='<p style="color:#363636;">* Required field.</p><br><br></div>',e+='<div id="AudioVideoHtml" class="settingsSubSection" style="display:none;">',e+="<div class=UiText>"+lang.speaker+":</div>",e+='<div style="text-align:center"><select id=playbackSrc style="width:100%"></select></div>',e+="<div class=Settings_VolumeOutput_Container><div id=Settings_SpeakerOutput class=Settings_VolumeOutput></div></div>",e+='<div><button class=on_white id=preview_output_play><i class="fa fa-play"></i></button><button class=on_white id=preview_output_pause><i class="fa fa-pause"></i></button></div>',e+="<br><div class=UiText>"+lang.ring_device+":</div>",e+='<div style="text-align:center"><select id=ringDevice style="width:100%"></select></div>',e+="<div class=Settings_VolumeOutput_Container><div id=Settings_RingerOutput class=Settings_VolumeOutput></div></div>",e+='<div><button class=on_white id=preview_ringer_play><i class="fa fa-play"></i></button></div>',e+="<br><div class=UiText>"+lang.microphone+":</div>",e+='<div style="text-align:center"><select id=microphoneSrc style="width:100%"></select></div>',e+="<div class=Settings_VolumeOutput_Container><div id=Settings_MicrophoneOutput class=Settings_VolumeOutput></div></div>",e+="<br><br><div><input type=checkbox id=Settings_AutoGainControl><label for=Settings_AutoGainControl> "+lang.auto_gain_control+"<label></div>",e+="<div><input type=checkbox id=Settings_EchoCancellation><label for=Settings_EchoCancellation> "+lang.echo_cancellation+"<label></div>",e+="<div><input type=checkbox id=Settings_NoiseSuppression><label for=Settings_NoiseSuppression> "+lang.noise_suppression+"<label></div>",e+="<br><div class=UiText>"+lang.camera+":</div>",e+='<div style="text-align:center"><select id=previewVideoSrc style="width:100%"></select></div>',e+="<br><div class=UiText>"+lang.frame_rate+":</div>",e+="<div class=pill-nav>",e+='<input name=Settings_FrameRate id=r40 type=radio value="2"><label class=radio_pill for=r40>2</label>',e+='<input name=Settings_FrameRate id=r41 type=radio value="5"><label class=radio_pill for=r41>5</label>',e+='<input name=Settings_FrameRate id=r42 type=radio value="10"><label class=radio_pill for=r42>10</label>',e+='<input name=Settings_FrameRate id=r43 type=radio value="15"><label class=radio_pill for=r43>15</label>',e+='<input name=Settings_FrameRate id=r44 type=radio value="20"><label class=radio_pill for=r44>20</label>',e+='<input name=Settings_FrameRate id=r45 type=radio value="25"><label class=radio_pill for=r45>25</label>',e+='<input name=Settings_FrameRate id=r46 type=radio value="30"><label class=radio_pill for=r46>30</label>',e+='<input name=Settings_FrameRate id=r47 type=radio value=""><label class=radio_pill for=r47><i class="fa fa-trash"></i></label>',e+="</div>",e+="<br><br><div class=UiText>"+lang.quality+":</div>",e+="<div class=pill-nav>",e+='<input name=Settings_Quality id=r30 type=radio value="160"><label class=radio_pill for=r30><i class="fa fa-video-camera" style="transform: scale(0.4)"></i> HQVGA</label>',e+='<input name=Settings_Quality id=r31 type=radio value="240"><label class=radio_pill for=r31><i class="fa fa-video-camera" style="transform: scale(0.6)"></i> QVGA</label>',e+='<input name=Settings_Quality id=r32 type=radio value="480"><label class=radio_pill for=r32><i class="fa fa-video-camera" style="transform: scale(0.8)"></i> VGA</label>',e+='<input name=Settings_Quality id=r33 type=radio value="720"><label class=radio_pill for=r33><i class="fa fa-video-camera" style="transform: scale(1)"></i> HD</label>',e+='<input name=Settings_Quality id=r34 type=radio value=""><label class=radio_pill for=r34><i class="fa fa-trash"></i></label>',e+="</div>",e+="<br><br><div class=UiText>"+lang.image_orientation+":</div>",e+="<div class=pill-nav>",e+='<input name=Settings_Oriteation id=r20 type=radio value="rotateY(0deg)"><label class=radio_pill for=r20><i class="fa fa-address-card" style="transform: rotateY(0deg)"></i> Normal</label>',e+='<input name=Settings_Oriteation id=r21 type=radio value="rotateY(180deg)"><label class=radio_pill for=r21><i class="fa fa-address-card" style="transform: rotateY(180deg)"></i> Mirror</label>',e+="</div>",e+="<br><br><div class=UiText>"+lang.aspect_ratio+":</div>",e+="<div class=pill-nav>",e+='<input name=Settings_AspectRatio id=r10 type=radio value="1"><label class=radio_pill for=r10><i class="fa fa-square-o" style="transform: scaleX(1); margin-left: 7px; margin-right: 7px"></i> 1:1</label>',e+='<input name=Settings_AspectRatio id=r11 type=radio value="1.33"><label class=radio_pill for=r11><i class="fa fa-square-o" style="transform: scaleX(1.33); margin-left: 5px; margin-right: 5px;"></i> 4:3</label>',e+='<input name=Settings_AspectRatio id=r12 type=radio value="1.77"><label class=radio_pill for=r12><i class="fa fa-square-o" style="transform: scaleX(1.77); margin-right: 3px;"></i> 16:9</label>',e+='<input name=Settings_AspectRatio id=r13 type=radio value=""><label class=radio_pill for=r13><i class="fa fa-trash"></i></label>',e+="</div>",e+="<br><br><div class=UiText>"+lang.preview+":</div>",e+='<div style="text-align:center; margin-top:10px"><video id="local-video-preview" class="previewVideo"></video></div>',e+="<br><div class=UiText>"+lang.video_conference_extension+":</div>",e+="<div><input id=Video_Conf_Extension class=UiInputText type=text placeholder='"+lang.video_conference_extension_example+"' value='"+getDbItem("VidConfExtension","")+"'></div>",e+="<br><div class=UiText>"+lang.video_conference_window_width+":</div>",e+="<div><input id=Video_Conf_Window_Width class=UiInputText type=text placeholder='"+lang.video_conf_window_width_explanation+"' value='"+getDbItem("VidConfWindowWidth","")+"'></div>","superadmin"==getDbItem("userrole","")){e+="<div id=confTableSection>"+lang.external_conf_users+"</div>",e+="<div class=confTable><table id=vidConfExternalTable>",e+="<tr class=btnTableRow><td><label for=extConfExtension id=extensionThLabel class=confExtLabels>Extension</label></td><td><label for=extConfExtensionPass id=extPassThLabel class=confExtLabels>SIP Password</label></td><td><label for=extConfExtensionLink id=extLinkThLabel class=confExtLabels>Link</label></td></tr>";for(var i=0;i<getDbItem("externalUserConfElem","");i++)e+="<tr class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension value='"+getDbItem("extUserExtension-"+i,"")+"' disabled=\"disabled\" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass value='"+getDbItem("extUserExtensionPass-"+i,"")+"' disabled=\"disabled\"/></td><td><input type=text class=extConfExtensionLink name=extConfExtensionLink value='"+getDbItem("confAccessLink-"+i,"")+'\' /></td><td><span class="copyToClipboard"><i class="fa fa-clipboard" aria-hidden="true" title="Copy link to clipboard."></i></span></td><td><span class="deleteExtRow" title="Delete extension data from database.">X</span></td><td><input type=submit class=saveExtConfExtension value="Edit" title="Edit this row." /></td></tr>';e+='<tr id=emptyExtRow class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension placeholder="Eg: 711" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass placeholder="Eg: d5?W?9q?8rg*R9!eFrVth?9" /></td><td><input type=text class=extConfExtensionLink name=extConfExtensionLink placeholder="Generated on \'Save\'" disabled="disabled" /></td><td><span class="copyToClipboard"><i class="fa fa-clipboard" aria-hidden="true" title="Copy link to clipboard."></i></span></td><td><span class="deleteExtRow deleteExtRowDisabled" title="Delete extension data from database.">X</span></td><td><input type=submit class=saveExtConfExtension value=Save title="Save this row." /></td></tr>',e+="</table></div>",e+="<button id=add_New_External_User>Add External User</button>"}e+="<br><br></div>",e+='<div id="AppearanceHtml" class="settingsSubSection" style="display:none;">',e+='<div id=ImageCanvas style="width:150px; height:150px;"></div>',e+='<label for=fileUploader class=customBrowseButton style="margin-left: 200px; margin-top: -2px;">Select File</label>',e+="<div><input id=fileUploader type=file></div>",e+='<div style="margin-top: 50px"></div>',e+="</div>",e+='<div id="NotificationsHtml" class="settingsSubSection" style="display:none;">',e+="<div class=UiText>"+lang.notifications+":</div>",e+='<div id="notificationsCheck"><input type=checkbox id=Settings_Notifications><label for=Settings_Notifications> '+lang.enable_onscreen_notifications+"<label></div>",e+="</div>",e+='<div id="RoundcubeEmailHtml" class="settingsSubSection" style="display:none;">',e+="<div class=UiText>"+lang.email_integration+":</div>",e+='<div id="enableRCcheck"><input id=emailIntegration type=checkbox ><label for=emailIntegration> '+lang.enable_roundcube_integration+"<label></div>",e+="<div class=UiText>"+lang.roundcube_domain+":</div>",e+="<div><input id=RoundcubeDomain class=UiInputText type=text placeholder='Roundcube domain (Eg: mail.example.com).' value='"+getDbItem("rcDomain","")+"'></div>",e+="<div class=UiText>"+lang.roundcube_user+":</div>",e+="<div><input id=RoundcubeUser class=UiInputText type=text placeholder='Roundcube login user (Eg: john.doe@example.com or john_doe).' value='"+getDbItem("RoundcubeUser","")+"'></div>",e+="<div class=UiText>"+lang.roundcube_password+":</div>",e+="<div><input id=RoundcubePass class=UiInputText type=password placeholder='Roundcube login password.' value='"+getDbItem("RoundcubePass","")+"'></div>",e+="<div class=UiText>"+lang.rc_basic_auth_user+":</div>",e+="<div><input id=rcBasicAuthUser class=UiInputText type=text placeholder='If you have a Roundcube basic auth user, enter it here.' value='"+getDbItem("rcBasicAuthUser","")+"'></div>",e+="<div class=UiText>"+lang.rc_basic_auth_password+":</div>",e+="<div><input id=rcBasicAuthPass class=UiInputText type=password placeholder='If you have a Roundcube basic auth password, enter it here.' value='"+getDbItem("rcBasicAuthPass","")+"'></div>",e+="<br><br></div>",e+='<div id="ChangePasswordHtml" class="settingsSubSection" style="display:none;">',e+="<div class=UiText>"+lang.current_user_password+":</div>",e+="<div><input id=Current_User_Password class=UiInputText type=password placeholder='Enter your current Roundpin user password.' value=''></div>",e+="<div class=UiText>"+lang.new_user_password+":</div>",e+="<div><input id=New_User_Password class=UiInputText type=password placeholder='Enter your new Roundpin user password.' value=''></div>",e+="<div class=UiText>"+lang.repeat_new_user_password+":</div>",e+="<div><input id=Repeat_New_User_Password class=UiInputText type=password placeholder='Enter your new Roundpin user password again.' value=''></div><br>",e+="<div><input id=Save_New_User_Password type=button value='Save New Password' onclick='saveNewUserPassword()' ></div>",e+="<br><br></div>",e+='<div id="ChangeEmailHtml" class="settingsSubSection" style="display:none;">',e+="<div class=UiText>"+lang.current_user_email+":</div>",e+="<div><input id=Current_User_Email class=UiInputText type=text placeholder='Enter your current Roundpin email address.' value=''></div>",e+="<div class=UiText>"+lang.new_user_email+":</div>",e+="<div><input id=New_User_Email class=UiInputText type=text placeholder='Enter your new email address.' value=''></div>",e+="<div class=UiText>"+lang.repeat_new_user_email+":</div>",e+="<div><input id=Repeat_New_User_Email class=UiInputText type=text placeholder='Enter your new email address again.' value=''></div><br>",e+="<div><input id=Save_New_User_Email type=button value='Save New Email' onclick='saveNewUserEmail()' ></div>",e+="<br><br></div>",e+='<div id="CloseAccountHtml" class="settingsSubSection" style="display:none;">',e+="<div class=UiText>"+lang.if_you_want_to_close_account+":</div><br><br>",e+="<div><input id=Close_User_Account type=button value='Close User Account' onclick='closeUserAccount()' ></div>",e+="<br><br></div>",e+="</div></div></div>";$.jeegoopopup.open({title:"<span id=settingsTitle>Settings</span>",html:e,width:"520",height:"500",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"configPopup",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append('<div id="bottomButtonsConf"><button id="save_button_conf">Save</button><button id="cancel_button_conf">Cancel</button></div>'),$("#jg_popup_l").append('<table id=leftPanelSettings cellspacing=14 cellpadding=0 style="width:184px;margin-left:8px;margin-top:14px;font-size:15px;"><tr id=ConnectionSettingsRow><td class=SettingsSection>Connection Settings</td></tr><tr id=AudioAndVideoRow><td class=SettingsSection>Audio & Video</td></tr><tr id=ProfilePictureRow><td class=SettingsSection>Profile Picture</td></tr><tr id=NotificationsRow><td class=SettingsSection>Notifications</td></tr><tr id=RoundcubeEmailRow><td class=SettingsSection>Email Integration</td></tr><tr id=ChangePasswordRow><td class=SettingsSection>Change Password</td></tr><tr id=ChangeEmailRow><td class=SettingsSection>Change Email</td></tr><tr id=CloseAccountRow><td class=SettingsSection>Close Account</td></tr></table>'),1==getDbItem("useRoundcube","")?$("#emailIntegration").prop("checked",!0):$("#emailIntegration").prop("checked",!1),$("#ConnectionSettingsRow td").addClass("selectedSettingsSection"),$("#ConnectionSettingsRow").click((function(){$(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#AccountHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#ConnectionSettingsRow td").addClass("selectedSettingsSection")})),$("#ProfilePictureRow").click((function(){$(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#AppearanceHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#ProfilePictureRow td").addClass("selectedSettingsSection")})),$("#NotificationsRow").click((function(){$(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#NotificationsHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#NotificationsRow td").addClass("selectedSettingsSection")})),$("#RoundcubeEmailRow").click((function(){$(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#RoundcubeEmailHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#RoundcubeEmailRow td").addClass("selectedSettingsSection")})),$("#ChangePasswordRow").click((function(){$(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#ChangePasswordHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#ChangePasswordRow td").addClass("selectedSettingsSection")})),$("#ChangeEmailRow").click((function(){$(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#ChangeEmailHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#ChangeEmailRow td").addClass("selectedSettingsSection")})),$("#CloseAccountRow").click((function(){$(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#CloseAccountHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#CloseAccountRow td").addClass("selectedSettingsSection")}));var n=$(window).width()-192,a=$(window).height()-98;n<520||a<500?($.jeegoopopup.width(n).height(a),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(520).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show()),$(window).resize((function(){n=$(window).width()-192,a=$(window).height()-98,$.jeegoopopup.center(),n<520||a<500?($.jeegoopopup.width(n).height(a),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(520).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show())})),$("#minimizeImg").click((function(){$.jeegoopopup.width(520).height(500),$.jeegoopopup.center(),$("#maximizeImg").show(),$("#minimizeImg").hide()})),$("#maximizeImg").click((function(){$.jeegoopopup.width(n).height(a),$.jeegoopopup.center(),$("#minimizeImg").show(),$("#maximizeImg").hide()}));var o=$("#playbackSrc"),l=$("#preview_output_play"),s=$("#preview_ringer_play"),r=$("#preview_output_pause"),d=$("#microphoneSrc");$("#Settings_AutoGainControl").prop("checked",AutoGainControl),$("#Settings_EchoCancellation").prop("checked",EchoCancellation),$("#Settings_NoiseSuppression").prop("checked",NoiseSuppression);var c=$("#previewVideoSrc"),u=$("input[name=Settings_Oriteation]");u.each((function(){this.value==MirrorVideo&&$(this).prop("checked",!0)})),$("#local-video-preview").css("transform",MirrorVideo);var p=$("input[name=Settings_FrameRate]");p.each((function(){this.value==maxFrameRate&&$(this).prop("checked",!0)}));var g=$("input[name=Settings_Quality]");g.each((function(){this.value==videoHeight&&$(this).prop("checked",!0)}));var m=$("input[name=Settings_AspectRatio]");m.each((function(){this.value==videoAspectRatio&&$(this).prop("checked",!0)}));$("#ringTone");var f=$("#ringDevice");m.change((function(){console.log("Call to change Aspect Ratio ("+this.value+")");var e=$("#local-video-preview").get(0);e.muted=!0,e.playsinline=!0,e.autoplay=!0,e.srcObject.getTracks().forEach((function(e){e.stop()}));var t={audio:!1,video:{deviceId:"default"!=c.val()?{exact:c.val()}:"default"}};""!=$("input[name=Settings_FrameRate]:checked").val()&&(t.video.frameRate=$("input[name=Settings_FrameRate]:checked").val()),""!=$("input[name=Settings_Quality]:checked").val()&&(t.video.height=$("input[name=Settings_Quality]:checked").val()),""!=this.value&&(t.video.aspectRatio=this.value),console.log("Constraints:",t);var i=new MediaStream;navigator.mediaDevices&&navigator.mediaDevices.getUserMedia(t).then((function(t){var n=t.getVideoTracks()[0];i.addTrack(n),e.srcObject=i,e.onloadedmetadata=function(t){e.play()}})).catch((function(e){console.error(e),AlertConfigExtWindow(lang.alert_error_user_media,lang.error)}))})),g.change((function(){console.log("Call to change Video Height ("+this.value+")");var e=$("#local-video-preview").get(0);e.muted=!0,e.playsinline=!0,e.autoplay=!0,e.srcObject.getTracks().forEach((function(e){e.stop()}));var t={audio:!1,video:{deviceId:"default"!=c.val()?{exact:c.val()}:"default"}};""!=$("input[name=Settings_FrameRate]:checked").val()&&(t.video.frameRate=$("input[name=Settings_FrameRate]:checked").val()),this.value&&(t.video.height=this.value),""!=$("input[name=Settings_AspectRatio]:checked").val()&&(t.video.aspectRatio=$("input[name=Settings_AspectRatio]:checked").val()),console.log("Constraints:",t);var i=new MediaStream;navigator.mediaDevices&&navigator.mediaDevices.getUserMedia(t).then((function(t){var n=t.getVideoTracks()[0];i.addTrack(n),e.srcObject=i,e.onloadedmetadata=function(t){e.play()}})).catch((function(e){console.error(e),AlertConfigExtWindow(lang.alert_error_user_media,lang.error)}))})),p.change((function(){console.log("Call to change Frame Rate ("+this.value+")");var e=$("#local-video-preview").get(0);e.muted=!0,e.playsinline=!0,e.autoplay=!0,e.srcObject.getTracks().forEach((function(e){e.stop()}));var t={audio:!1,video:{deviceId:"default"!=c.val()?{exact:c.val()}:"default"}};""!=this.value&&(t.video.frameRate=this.value),""!=$("input[name=Settings_Quality]:checked").val()&&(t.video.height=$("input[name=Settings_Quality]:checked").val()),""!=$("input[name=Settings_AspectRatio]:checked").val()&&(t.video.aspectRatio=$("input[name=Settings_AspectRatio]:checked").val()),console.log("Constraints:",t);var i=new MediaStream;navigator.mediaDevices&&navigator.mediaDevices.getUserMedia(t).then((function(t){var n=t.getVideoTracks()[0];i.addTrack(n),e.srcObject=i,e.onloadedmetadata=function(t){e.play()}})).catch((function(e){console.error(e),AlertConfigExtWindow(lang.alert_error_user_media,lang.error)}))})),d.change((function(){console.log("Call to change Microphone ("+this.value+")");try{window.SettingsMicrophoneStream.getTracks().forEach((function(e){e.stop()})),window.SettingsMicrophoneStream=null}catch(e){}try{soundMeter=window.SettingsMicrophoneSoundMeter,soundMeter.stop(),window.SettingsMicrophoneSoundMeter=null}catch(e){}var e={audio:{deviceId:{exact:this.value}},video:!1},t=new MediaStream;navigator.mediaDevices.getUserMedia(e).then((function(e){var i=e.getAudioTracks()[0];null!=i&&(t.addTrack(i),window.SettingsMicrophoneStream=t,window.SettingsMicrophoneSoundMeter=MeterSettingsOutput(t,"Settings_MicrophoneOutput","width",50))})).catch((function(e){console.log("Failed to getUserMedia",e)}))})),o.change((function(){console.log("Call to change Speaker ("+this.value+")");var e=window.SettingsOutputAudio;null!=e&&void 0!==e.sinkId&&e.setSinkId(this.value).then((function(){console.log("sinkId applied to audioObj:",this.value)})).catch((function(e){console.warn("Failed not apply setSinkId.",e)}))})),l.click((function(){try{window.SettingsOutputAudio.pause()}catch(e){}window.SettingsOutputAudio=null;try{window.SettingsOutputStream.getTracks().forEach((function(e){e.stop()}))}catch(e){}window.SettingsOutputStream=null;try{window.SettingsOutputStreamMeter.stop()}catch(e){}window.SettingsOutputStreamMeter=null,console.log("Audio:",audioBlobs.speaker_test.url);var e=new Audio(audioBlobs.speaker_test.blob);e.preload="auto",e.onplay=function(){var t=new MediaStream;if(void 0!==e.captureStream)t=e.captureStream();else{if(void 0!==e.mozCaptureStream)return;if(void 0===e.webkitCaptureStream)return void console.warn("Cannot display Audio Levels");t=e.webkitCaptureStream()}window.SettingsOutputStream=t,window.SettingsOutputStreamMeter=MeterSettingsOutput(t,"Settings_SpeakerOutput","width",50)},e.oncanplaythrough=function(t){void 0!==e.sinkId&&e.setSinkId(o.val()).then((function(){console.log("Set sinkId to:",o.val())})).catch((function(e){console.warn("Failed not apply setSinkId.",e)})),e.play().then((function(){})).catch((function(e){console.warn("Unable to play audio file",e)})),console.log("Playing sample audio file... ")},window.SettingsOutputAudio=e})),r.click((function(){window.SettingsOutputAudio.paused?window.SettingsOutputAudio.play():window.SettingsOutputAudio.pause()})),s.click((function(){try{window.SettingsRingerAudio.pause()}catch(e){}window.SettingsRingerAudio=null;try{window.SettingsRingerStream.getTracks().forEach((function(e){e.stop()}))}catch(e){}window.SettingsRingerStream=null;try{window.SettingsRingerStreamMeter.stop()}catch(e){}window.SettingsRingerStreamMeter=null,console.log("Audio:",audioBlobs.Ringtone.url);var e=new Audio(audioBlobs.Ringtone.blob);e.preload="auto",e.onplay=function(){var t=new MediaStream;if(void 0!==e.captureStream)t=e.captureStream();else{if(void 0!==e.mozCaptureStream)return;if(void 0===e.webkitCaptureStream)return void console.warn("Cannot display Audio Levels");t=e.webkitCaptureStream()}window.SettingsRingerStream=t,window.SettingsRingerStreamMeter=MeterSettingsOutput(t,"Settings_RingerOutput","width",50)},e.oncanplaythrough=function(t){void 0!==e.sinkId&&e.setSinkId(f.val()).then((function(){console.log("Set sinkId to:",f.val())})).catch((function(e){console.warn("Failed not apply setSinkId.",e)})),e.play().then((function(){})).catch((function(e){console.warn("Unable to play audio file",e)})),console.log("Playing sample audio file... ")},window.SettingsRingerAudio=e})),u.change((function(){console.log("Call to change Orientation ("+this.value+")"),$("#local-video-preview").css("transform",this.value)})),c.change((function(){console.log("Call to change WebCam ("+this.value+")");var e=$("#local-video-preview").get(0);e.muted=!0,e.playsinline=!0,e.autoplay=!0,e.srcObject.getTracks().forEach((function(e){e.stop()}));var t={audio:!1,video:{deviceId:"default"!=this.value?{exact:this.value}:"default"}};""!=$("input[name=Settings_FrameRate]:checked").val()&&(t.video.frameRate=$("input[name=Settings_FrameRate]:checked").val()),""!=$("input[name=Settings_Quality]:checked").val()&&(t.video.height=$("input[name=Settings_Quality]:checked").val()),""!=$("input[name=Settings_AspectRatio]:checked").val()&&(t.video.aspectRatio=$("input[name=Settings_AspectRatio]:checked").val()),console.log("Constraints:",t);var i=new MediaStream;navigator.mediaDevices&&navigator.mediaDevices.getUserMedia(t).then((function(t){var n=t.getVideoTracks()[0];i.addTrack(n),e.srcObject=i,e.onloadedmetadata=function(t){e.play()}})).catch((function(e){console.error(e),AlertConfigExtWindow(lang.alert_error_user_media,lang.error)}))})),$("#AudioAndVideoRow").click((function(){if($(".settingsSubSection").each((function(){$(this).css("display","none")})),$("#AudioVideoHtml").css("display","block"),$(".SettingsSection").each((function(){$(this).removeClass("selectedSettingsSection")})),$("#AudioAndVideoRow td").addClass("selectedSettingsSection"),0==videoAudioCheck){videoAudioCheck=1;var e=$("#local-video-preview").get(0);e.muted=!0,e.playsinline=!0,e.autoplay=!0;var t=new MediaStream,i=new MediaStream;navigator.mediaDevices?navigator.mediaDevices.enumerateDevices().then((function(n){for(var a=getVideoSrcID(),l=!1,s=getAudioSrcID(),r=!1,u=!1,p=!1,g=!1,m=0;m<n.length;++m)console.log("Found Device ("+n[m].kind+"): ",n[m].label),"audioinput"===n[m].kind?(u=!0,"default"!=s&&n[m].deviceId==s&&(r=!0)):"audiooutput"===n[m].kind?p=!0:"videoinput"===n[m].kind&&(g=!0,"default"!=a&&n[m].deviceId==a&&(l=!0));var v={audio:u,video:g};u&&(v.audio={deviceId:"default"},r&&(v.audio.deviceId={exact:s})),g&&(v.video={deviceId:"default"},l&&(v.video.deviceId={exact:a})),""!=$("input[name=Settings_FrameRate]:checked").val()&&(v.video.frameRate=$("input[name=Settings_FrameRate]:checked").val()),""!=$("input[name=Settings_Quality]:checked").val()&&(v.video.height=$("input[name=Settings_Quality]:checked").val()),""!=$("input[name=Settings_AspectRatio]:checked").val()&&(v.video.aspectRatio=$("input[name=Settings_AspectRatio]:checked").val()),console.log("Get User Media",v),navigator.mediaDevices.getUserMedia(v).then((function(n){var a=n.getVideoTracks().length>=1?n.getVideoTracks()[0]:null;g&&null!=a?(t.addTrack(a),e.srcObject=t,e.onloadedmetadata=function(t){e.play()}):console.warn("No video / webcam devices found. Video Calling will not be possible.");var o=n.getAudioTracks().length>=1?n.getAudioTracks()[0]:null;return u&&null!=o?(i.addTrack(o),window.SettingsMicrophoneStream=i,window.SettingsMicrophoneSoundMeter=MeterSettingsOutput(i,"Settings_MicrophoneOutput","width",50)):console.warn("No microphone devices found. Calling will not be possible."),$("#Settings_SpeakerOutput").css("width","0%"),p||(console.log("No speaker devices found, make sure one is plugged in."),$("#playbackSrc").hide(),$("#RingDeviceSection").hide()),navigator.mediaDevices.enumerateDevices()})).then((function(e){for(var t=0;t<e.length;++t){console.log("Found Device ("+e[t].kind+") Again: ",e[t].label,e[t].deviceId);var i=e[t],n=i.deviceId,a=i.label;a.indexOf("(")>0&&(a=a.substring(0,a.indexOf("("))),(l=$("<option/>")).prop("value",n),"audioinput"===i.kind?(l.text(""!=a?a:"Microphone"),getAudioSrcID()==n&&l.prop("selected",!0),d.append(l)):"audiooutput"===i.kind?(l.text(""!=a?a:"Speaker"),getAudioOutputID()==n&&l.prop("selected",!0),o.append(l),f.append(l.clone())):"videoinput"===i.kind&&(getVideoSrcID()==n&&l.prop("selected",!0),l.text(""!=a?a:"Webcam"),c.append(l))}var l;c.children("option").length>0&&((l=$("<option/>")).prop("value","default"),"default"!=getVideoSrcID()&&""!=getVideoSrcID()&&"null"!=getVideoSrcID()||l.prop("selected",!0),l.text("(Default)"),c.append(l))})).catch((function(e){console.error(e),AlertConfigExtWindow(lang.alert_error_user_media,lang.error)}))})).catch((function(e){console.error("Error getting Media Devices",e)})):AlertConfigExtWindow(lang.alert_error_user_media,lang.error)}}));var v=$("#Settings_Notifications");v.prop("checked",NotificationsActive),v.change((function(){this.checked&&"granted"!=Notification.permission&&(checkNotificationPromise()?Notification.requestPermission().then((function(e){console.log(e),HandleNotifyPermission(e)})):Notification.requestPermission((function(e){console.log(e),HandleNotifyPermission(e)})))})),$("#vidConfExternalTable").on("click",".saveExtConfExtension",(function(){if("Save"==$(this).val()){var e=$(this).closest("tr").find("input.extConfExtension").val(),t=$(this).closest("tr").find("input.extConfExtensionPass").val(),i=localDB.getItem("wssServer");""!=e&&""!=t?e.length<200&&t.length<400?/^[a-zA-Z0-9]+$/.test(e)?($.ajax({type:"POST",url:"save-update-external-user-conf.php",dataType:"JSON",data:{username:userName,exten_for_external:e,exten_for_ext_pass:t,wss_server:i,s_ajax_call:validateSToken},success:function(e){"The data has been successfully saved to the database !"==e.result?(getExternalUserConfFromSqldb(),alert("The data has been successfully saved to the database ! To see the result, please reopen this window !"),$("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),closeVideoAudio(),$.jeegoopopup.close()):alert(e.result)},error:function(e){alert("An error occurred while trying to save the data to the database !")}}),$(this).closest('[class="btnTableRow"]').find('[class="extConfExtension"]').attr("disabled",!0),$(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionPass"]').attr("disabled",!0),$(this).attr("value","Edit"),$(this).prop("title","Edit this row.")):alert("The extension should contain only numbers and letters."):alert("The extension and/or the SIP password don't have a reasonable length."):alert('Please fill in both the "Extension" and the "SIP Password" fields !')}else $(this).closest('[class="btnTableRow"]').find('[class="extConfExtension"]').attr("disabled",!1),$(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionPass"]').attr("disabled",!1),$(this).attr("value","Save"),$(this).prop("title","Save this row.")})),$("#vidConfExternalTable").on("click",".deleteExtRow",(function(){var e=$(this).closest('[class="btnTableRow"]').find('[class="extConfExtension"]').val();""!=e&&confirm("Do you really want to delete this row from this window and from the database ?")&&($.ajax({type:"POST",url:"remove-external-user-ext-data.php",dataType:"JSON",data:{username:userName,exten_for_external:e,s_ajax_call:validateSToken},success:function(e){$(this).closest("tr").find("input.extConfExtension").empty(),$(this).closest("tr").find("input.extConfExtensionPass").empty(),$(this).closest("tr").find("input.extConfExtensionLink").empty(),getExternalUserConfFromSqldb(),alert("The data has been permanently removed !")},error:function(e){alert("An error occurred while trying to remove the data !")}}),$(this).closest('[class="btnTableRow"]').hide())})),$(".copyToClipboard").mouseenter((function(){""!=$(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionLink"]').val()&&($(this).css("color","#424242"),$(this).css("cursor","pointer"))})),$(".copyToClipboard").mouseleave((function(){$(this).css("color","#cccccc")})),$(".copyToClipboard").click((function(){if(""!=$(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionLink"]').val()){var e=$("<input>");$("body").append(e),e.val($(this).closest('[class="btnTableRow"]').find('[class="extConfExtensionLink"]').val()).select(),document.execCommand("Copy"),e.remove(),alert("The link has been copied to your clipboard!")}}));var h=getDbItem("externalUserConfElem","");"undefined"!==h&&"null"!=h&&0!=h&&$("#emptyExtRow").hide(),$("#add_New_External_User").click((function(){$("#vidConfExternalTable").append('<tr class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension placeholder="Eg: 711" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass placeholder="Eg: d5?W?9q?8rg*R9!eFrVth?9" /></td><td><input type=text class="extConfExtensionLink" name=extConfExtensionLink placeholder="Generated on \'Save\'" disabled="disabled" /></td><td><span class="copyToClipboard"><i class="fa fa-clipboard" aria-hidden="true" title="Copy link to clipboard."></i></span></td><td><span class="deleteExtRow deleteExtRowDisabled" title="Delete extension data from database.">X</span></td><td><input type=submit class="saveExtConfExtension" value="Save" title="Save this row." /></td></tr>')})),cropper=$("#ImageCanvas").croppie({viewport:{width:150,height:150,type:"circle"}}),$("#ImageCanvas").croppie("bind",{url:getPicture("profilePicture")}).then((function(){$(".cr-slider").attr({min:.5,max:3})})),$("#fileUploader").change((function(){var e=$(this).prop("files");if(1==e.length){var t=Math.floor(1e9*Math.random()),i=e[0],n=i.name,a=i.size;if(a<=52428800){console.log("Adding ("+t+"): "+n+" of size: "+a+"bytes");var o=new FileReader;o.Name=n,o.UploadId=t,o.Size=a,o.onload=function(e){$("#ImageCanvas").croppie("bind",{url:e.target.result})},o.readAsDataURL(i)}else Alert(lang.alert_file_size,lang.error)}else Alert(lang.alert_single_file,lang.error)})),$("#save_button_conf").click((function(){null==localDB.getItem("profileUserID")&&localDB.setItem("profileUserID",uID());var e=$("#Configure_Account_wssServer").val();if(/^[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(e))var t=e;else{t="";alert("The WebSocket domain that you entered is not a valid domain name!")}var i=$("#Configure_Account_WebSocketPort").val();if(/^[0-9]+$/.test(i))var n=i;else{n="";alert("The web socket port that you entered is not a valid port!")}var a=$("#Configure_Account_ServerPath").val();if(/^[A-Za-z0-9\/]+$/.test(a))var o=a;else{o="";alert("The server path that you entered is not a valid server path!")}var l=$("#Configure_Account_profileName").val();if(/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(l))var s=l;else{s="";alert("The profile name that you entered is not a valid profile name!")}var r=$("#Configure_Account_SipUsername").val();if(/^[A-Za-z0-9\-\.\_\@\*\!\?\&\~\(\)\[\]]+$/.test(r))var d=r;else{d="";alert("The SIP username that you entered is not a valid SIP username!")}var c=$("#Configure_Account_SipPassword").val();if(c.length<400)var u=c;else{u="";alert("The SIP password that you entered is too long!")}var p=$("#Configure_Account_StunServer").val();if(null!=p&&""!==p.trim())if(/^(\d+\.\d+\.\d+\.\d+:\d+)$|^([A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}:\d+)/.test(p));else{alert("The domain or IP or port number of the STUN server is not valid!")}else;if(null!=t&&""!==t.trim()&&null!=n&&""!==n.trim()&&null!=o&&""!==o.trim()&&null!=s&&""!==s.trim()&&null!=d&&""!==d.trim()&&null!=u&&""!==u.trim()){localDB.setItem("AudioOutputId",$("#playbackSrc").val()),localDB.setItem("VideoSrcId",$("#previewVideoSrc").val()),localDB.setItem("VideoHeight",$("input[name=Settings_Quality]:checked").val()),localDB.setItem("FrameRate",$("input[name=Settings_FrameRate]:checked").val()),localDB.setItem("AspectRatio",$("input[name=Settings_AspectRatio]:checked").val()),localDB.setItem("VideoOrientation",$("input[name=Settings_Oriteation]:checked").val()),localDB.setItem("AudioSrcId",$("#microphoneSrc").val()),localDB.setItem("AutoGainControl",$("#Settings_AutoGainControl").is(":checked")?"1":"0"),localDB.setItem("EchoCancellation",$("#Settings_EchoCancellation").is(":checked")?"1":"0"),localDB.setItem("NoiseSuppression",$("#Settings_NoiseSuppression").is(":checked")?"1":"0"),localDB.setItem("RingOutputId",$("#ringDevice").val());var g=$("#Video_Conf_Extension").val();if(/^[a-zA-Z0-9\*\#]+$/.test(g))var m=g;else{m="";alert("The extension that you entered in the 'Video Conference Extension' field is not a valid extension!")}localDB.setItem("VidConfExtension",m);var f=$("#Video_Conf_Window_Width").val();if(/^[0-9]+$/.test(f)&&Math.abs(f)<=100)var v=Math.abs(f);else{v="";alert("The percent value that you entered in the 'Percent of screen width ...' field is not valid!")}if(localDB.setItem("VidConfWindowWidth",v),localDB.setItem("Notifications",$("#Settings_Notifications").is(":checked")?"1":"0"),$("#emailIntegration").is(":checked")){if(!/^[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test($("#RoundcubeDomain").val()))return $("#emailIntegration").prop("checked",!1),$("#RoundcubeDomain").val(""),void alert("The Roundcube domain is not valid. After entering a valid Roundcube domain, please remember to check the checkbox 'Enable Roundcube email integration' again !");if(!/^[A-Za-z0-9\_\.\-\@\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]{1,300}$/.test($("#RoundcubeUser").val()))return $("#emailIntegration").prop("checked",!1),$("#RoundcubeUser").val(""),void alert("The Roundcube user is not valid. After entering a valid Roundcube user, please remember to check the checkbox 'Enable Roundcube email integration' again !");if(""==$("#RoundcubePass").val()||$("#RoundcubePass").val().length>300)return $("#emailIntegration").prop("checked",!1),$("#RoundcubePass").val(""),void alert("The Roundcube password is not valid. After entering a valid Roundcube password, please remember to check the checkbox 'Enable Roundcube email integration' again !");if($("#rcBasicAuthUser").val().length>300)return $("#rcBasicAuthUser").val(""),void alert("The Roundcube basic authentication user is not valid.");if($("#rcBasicAuthPass").val().length>300)return $("#rcBasicAuthPass").val(""),void alert("The Roundcube basic authentication password is not valid.")}$("#AppearanceHtml").css({display:"block",visibility:"hidden","margin-top":"-228px"}),$("#ImageCanvas").croppie("result",{type:"base64",size:"viewport",format:"png",quality:1,circle:!1}).then((function(e){localDB.setItem("profilePicture",e)})),setTimeout((function(){saveConfToSqldb()}),600)}else alert("All fields marked with an asterisk are required!")})),$("#closeImg").click((function(){$("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),closeVideoAudio(),$.jeegoopopup.close()})),$("#cancel_button_conf").click((function(){$("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),closeVideoAudio(),$.jeegoopopup.close()})),$("#jg_popup_overlay").click((function(){$("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),closeVideoAudio(),$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),closeVideoAudio(),$.jeegoopopup.close())}))}function checkNotificationPromise(){try{Notification.requestPermission().then()}catch(e){return!1}return!0}function HandleNotifyPermission(e){"granted"==e||Alert(lang.alert_notification_permission,lang.permission,(function(){console.log("Attempting to uncheck the checkbox..."),$("#Settings_Notifications").prop("checked",!1)}))}function EditBuddyWindow(e){$.jeegoopopup.close();var t=null,i=-1,n=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));if($.each(n.DataCollection,(function(n,a){if(a.uID==e||a.cID==e||a.gID==e)return t=a,i=n,!1})),null!=t){var a="<div id='EditContact'>";a+="<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>",a+="<div class='UiWindowField scroller'>",a+='<div id=ImageCanvas style="width:150px; height:150px"></div>',a+='<label for=ebFileUploader class=customBrowseButton style="margin-left: 200px; margin-top: -9px;">Select File</label>',a+="<div><input type=file id=ebFileUploader /></div>",a+='<div style="margin-top: 50px"></div>',a+="<div class=UiText>"+lang.display_name+":</div>",a+="<div><input id=AddSomeone_Name class=UiInputText type=text placeholder='"+lang.eg_display_name+"' value='"+(t.DisplayName&&"null"!=t.DisplayName&&"undefined"!=t.DisplayName?t.DisplayName:"")+"'></div>",a+="<div class=UiText>"+lang.title_description+":</div>","extension"==t.Type?a+="<div><input id=AddSomeone_Desc class=UiInputText type=text placeholder='"+lang.eg_general_manager+"' value='"+(t.Position&&"null"!=t.Position&&"undefined"!=t.Position?t.Position:"")+"'></div>":a+="<div><input id=AddSomeone_Desc class=UiInputText type=text placeholder='"+lang.eg_general_manager+"' value='"+(t.Description&&"null"!=t.Description&&"undefined"!=t.Description?t.Description:"")+"'></div>",a+="<div class=UiText>"+lang.internal_subscribe_extension+":</div>",a+="<div><input id=AddSomeone_Exten class=UiInputText type=text placeholder='"+lang.eg_internal_subscribe_extension+"' value='"+(t.ExtensionNumber&&"null"!=t.ExtensionNumber&&"undefined"!=t.ExtensionNumber?t.ExtensionNumber:"")+"'></div>",a+="<div class=UiText>"+lang.mobile_number+":</div>",a+="<div><input id=AddSomeone_Mobile class=UiInputText type=text placeholder='"+lang.eg_mobile_number+"' value='"+(t.MobileNumber&&"null"!=t.MobileNumber&&"undefined"!=t.MobileNumber?t.MobileNumber:"")+"'></div>",a+="<div class=UiText>"+lang.contact_number_1+":</div>",a+="<div><input id=AddSomeone_Num1 class=UiInputText type=text placeholder='"+lang.eg_contact_number_1+"' value='"+(t.ContactNumber1&&"null"!=t.ContactNumber1&&"undefined"!=t.ContactNumber1?t.ContactNumber1:"")+"'></div>",a+="<div class=UiText>"+lang.contact_number_2+":</div>",a+="<div><input id=AddSomeone_Num2 class=UiInputText type=text placeholder='"+lang.eg_contact_number_2+"' value='"+(t.ContactNumber2&&"null"!=t.ContactNumber2&&"undefined"!=t.ContactNumber2?t.ContactNumber2:"")+"'></div>",a+="<div class=UiText>"+lang.email+":</div>",a+="<div><input id=AddSomeone_Email class=UiInputText type=text placeholder='"+lang.email+"' value='"+(t.Email&&"null"!=t.Email&&"undefined"!=t.Email?t.Email:"")+"'></div>",a+="</div></div>",$.jeegoopopup.open({title:"Edit Contact",html:a,width:"640",height:"500",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"editContactPopup",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append("<div id=bottomButtons><button id=save_button>Save</button><button id=cancel_button>Cancel</button></div>");var o="";$.ajax({type:"POST",url:"get-contact-dbid.php",dataType:"JSON",data:{username:userName,contact_name:t.DisplayName,s_ajax_call:validateSToken},success:function(e){"success"==e.successorfailure?o=e.cntctDatabaseID:alert("Error while attempting to retrieve contact data from the database!")},error:function(e){alert("Error while attempting to retrieve contact data from the database!")}});$("#ImageCanvas").croppie({viewport:{width:150,height:150,type:"circle"}});"extension"==t.Type?$("#ImageCanvas").croppie("bind",{url:getPicture(t.uID,"extension")}).then((function(){$(".cr-slider").attr({min:.5,max:3})})):"contact"==t.Type?$("#ImageCanvas").croppie("bind",{url:getPicture(t.cID,"contact")}).then((function(){$(".cr-slider").attr({min:.5,max:3})})):"group"==t.Type&&$("#ImageCanvas").croppie("bind",{url:getPicture(t.gID,"group")}).then((function(){$(".cr-slider").attr({min:.5,max:3})})),$("#ebFileUploader").change((function(){var e=$(this).prop("files");if(1==e.length){var t=Math.floor(1e9*Math.random()),i=e[0],n=i.name,a=i.size;if(a<=52428800){console.log("Adding ("+t+"): "+n+" of size: "+a+"bytes");var o=new FileReader;o.Name=n,o.UploadId=t,o.Size=a,o.onload=function(e){$("#ImageCanvas").croppie("bind",{url:e.target.result})},o.readAsDataURL(i)}else Alert(lang.alert_file_size,lang.error)}else Alert(lang.alert_single_file,lang.error)})),$("#save_button").click((function(){var e=$("#AddSomeone_Name").val();if(null!=e&&""!==e.trim())if(/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(e)){t.LastActivity=utcDateNow(),t.DisplayName=e;var a=$("#AddSomeone_Desc").val();if(null!=a&&""!==a.trim())if(/^[A-Za-z0-9\s\-\.\'\"\[\]\(\)\{\}\_\!\?\~\@\%\^\&\*\+\>\<\;\:\=]+$/.test(a))var l=a;else{l="";alert("The title/description that you entered is not valid!")}else l="";"extension"==t.Type?t.Position=l:t.Description=l;var s=$("#AddSomeone_Exten").val();if(null!=s&&""!==s.trim())if(/^[a-zA-Z0-9\*\#]+$/.test(s))var r=s;else{r="";alert("The extension that you entered in the 'Extension (Internal)' field is not a valid extension!")}else r="";t.ExtensionNumber=r;var d=$("#AddSomeone_Mobile").val();if(null!=d&&""!==d.trim())if(/^[0-9\s\+\#]+$/.test(d))var c=d;else{c="";alert("The phone number that you entered in the 'Mobile Number' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs.")}else c="";t.MobileNumber=c;var u=$("#AddSomeone_Num1").val();if(null!=u&&""!==u.trim())if(/^[0-9\s\+\#]+$/.test(u))var p=u;else{p="";alert("The phone number that you entered in the 'Contact Number 1' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs.")}else p="";t.ContactNumber1=p;var g=$("#AddSomeone_Num2").val();if(null!=g&&""!==g.trim())if(/^[0-9\s\+\#]+$/.test(g))var m=g;else{m="";alert("The phone number that you entered in the 'Contact Number 2' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs.")}else m="";t.ContactNumber2=m;var f=$("#AddSomeone_Email").val();if(null!=f&&""!==f.trim())if(/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(f))var v=f;else{v="";alert("The email that you entered is not a valid email address!")}else v="";t.Email=v;$("#ImageCanvas").croppie("result",{type:"base64",size:"viewport",format:"png",quality:1,circle:!1}).then((function(e){if("extension"==t.Type){localDB.setItem("img-"+t.uID+"-extension",e),$("#contact-"+t.uID+"-picture-main").css("background-image","url("+getPicture(t.uID,"extension")+")"),$("#contact-"+t.uID+"-presence-main").html(t.Position);saveContactPicToSQLDB([t.DisplayName,localDB.getItem("img-"+t.uID+"-extension",e)])}else if("contact"==t.Type){localDB.setItem("img-"+t.cID+"-contact",e),$("#contact-"+t.cID+"-picture-main").css("background-image","url("+getPicture(t.cID,"contact")+")"),$("#contact-"+t.cID+"-presence-main").html(t.Description);saveContactPicToSQLDB([t.DisplayName,localDB.getItem("img-"+t.cID+"-contact",e)])}else if("group"==t.Type){localDB.setItem("img-"+t.gID+"-group",e),$("#contact-"+t.gID+"-picture-main").css("background-image","url("+getPicture(t.gID,"group")+")"),$("#contact-"+t.gID+"-presence-main").html(t.Description);saveContactPicToSQLDB([t.DisplayName,localDB.getItem("img-"+t.gID+"-group",e)])}UpdateBuddyList()})),n.DataCollection[i]=t,localDB.setItem(profileUserID+"-Buddies",JSON.stringify(n));updateContactToSQLDB([e,l,r,c,p,m,v,o]);for(var h=0;h<Buddies.length;h++)"extension"==t.Type?t.uID==Buddies[h].identity&&(Buddies[h].lastActivity=t.LastActivity,Buddies[h].CallerIDName=t.DisplayName,Buddies[h].Desc=t.Position):"contact"==t.Type?t.cID==Buddies[h].identity&&(Buddies[h].lastActivity=t.LastActivity,Buddies[h].CallerIDName=t.DisplayName,Buddies[h].Desc=t.Description):t.Type;UpdateBuddyList(),$.jeegoopopup.close(),$("#jg_popup_b").empty()}else alert("The display name that you entered is not a valid display name!");else alert("'Display Name' cannot be empty!")}));var l=$(window).width()-16,s=$(window).height()-110;l<656||s<500?($.jeegoopopup.width(l).height(s),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show()),$(window).resize((function(){l=$(window).width()-16,s=$(window).height()-110,$.jeegoopopup.center(),l<656||s<500?($.jeegoopopup.width(l).height(s),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show())})),$("#minimizeImg").click((function(){$.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#maximizeImg").show(),$("#minimizeImg").hide()})),$("#maximizeImg").click((function(){$.jeegoopopup.width(l).height(s),$.jeegoopopup.center(),$("#minimizeImg").show(),$("#maximizeImg").hide()})),$("#closeImg").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#cancel_button").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($.jeegoopopup.close(),$("#jg_popup_b").empty())}))}else Alert(lang.alert_not_found,lang.error)}function InitUi(){var e=$("#Phone");e.empty(),e.attr("class","pageContainer");var t=$("<div>");t.attr("id","leftContent"),t.attr("style","float:left; height: 100%; width:320px");var i='<table style="height:100%; width:100%" cellspacing=5 cellpadding=0>';i+='<tr><td class=logoSection style="height: 50px"><div id="smallLogo"><img src="images/small-logo.svg" /></div><div id="inLogoSection"><div id="emailInLogoSection" onclick="ShowEmailWindow()" title="Email"><i class="fa fa-envelope-o" aria-hidden="true"></i></div><div id="aboutInLogoSection" onclick="ShowAboutWindow()" title="About"><button id="aboutImg"></button></div><div id="shrinkLeftPanel" onclick="CollapseLeftPanel()" title="Collapse"><button id="collapseLeftPanel"></button></div></div></td></tr>',i+='<tr><td class=streamSection style="height: 82px">',i+="<div class=profileContainer>",i+='<div class=contact id=UserProfile style="margin-bottom:12px;">',i+='<div id=UserProfilePic class=buddyIcon title="Status"></div>',i+="<span id=reglink class=dotOffline></span>",i+='<span id=dereglink class=dotOnline style="display:none"><i class="fa fa-wifi" style="line-height: 14px; text-align: center; display: block;"></i></span>',i+='<span id=WebRtcFailed class=dotFailed style="display:none"><i class="fa fa-cross" style="line-height: 14px; text-align: center; display: block;"></i></span>',i+='<div class=contactNameText style="margin-right: 0px;"><i class="fa fa-phone-square"></i> <span id=UserDID></span> - <span id=UserCallID></span></div>',i+="<div id=regStatus class=presenceText> </div>",i+="</div>",i+="<div id=searchBoxAndIcons>",i+='<span class=searchClean><INPUT id=txtFindBuddy type=text autocomplete=none style="width:142px;" title="Find Contact"></span>',i+="<div id=ButtonsOnSearchLine>",i+="<button id=BtnFreeDial title='"+lang.dial_number+"'></button>",i+="<button id=LaunchVideoConf title='"+lang.launch_video_conference+'\'><i class="fa fa-users"></i></button>',i+="<button id=BtnSettings title='"+lang.account_settings+'\'><i class="fa fa-cog"></i></button>',i+="</div>",i+="</div>",i+="</div>",i+="</td></tr>",i+='<tr><td class=streamSection><div id=myContacts class="contactArea cleanScroller"></div></td></tr>',i+="</table>",t.html(i);var n=$("<div>");n.attr("id","rightContent"),n.attr("style","margin-left: 320px; height: 100%; overflow: auto;"),e.append(t),e.append(n),windowsCollection="",messagingCollection="",1==DisableFreeDial&&$("#BtnFreeDial").hide(),1==DisableBuddies&&$("#BtnAddSomeone").hide(),0==enabledGroupServices&&$("#BtnCreateGroup").hide(),$("#UserDID").html(profileUser),$("#UserCallID").html(profileName),$("#UserProfilePic").css("background-image","url('"+getPicture("profilePicture")+"')"),$("#txtFindBuddy").attr("placeholder",lang.find_someone),$("#txtFindBuddy").on("keyup",(function(e){UpdateBuddyList()})),$("#BtnFreeDial").on("click",(function(e){ShowDial(this)})),$("#BtnAddSomeone").attr("title",lang.add_contact),$("#BtnAddSomeone").on("click",(function(e){AddSomeoneWindow()})),$("#BtnCreateGroup").attr("title",lang.create_group),$("#BtnCreateGroup").on("click",(function(e){CreateGroupWindow()})),$("#LaunchVideoConf").on("click",(function(e){ShowLaunchVidConfMenu(this)})),$("#BtnSettings").on("click",(function(e){ShowAccountSettingsMenu(this)})),$("#UserProfile").on("click",(function(e){ShowMyProfileMenu(this)})),UpdateUI(),PopulateBuddyList(),null!=localDB.getItem("SelectedBuddy")&&(console.log("Selecting previously selected buddy...",localDB.getItem("SelectedBuddy")),SelectBuddy(localDB.getItem("SelectedBuddy")),UpdateUI()),PreloadAudioFiles(),CreateUserAgent(),getContactsFromSQLDB(),generateChatRSAKeys(getDbItem("SipUsername","")),removeTextChatUploads(getDbItem("SipUsername",""))}function PreloadAudioFiles(){audioBlobs.Alert={file:"Alert.mp3",url:hostingPrefex+"sounds/Alert.mp3"},audioBlobs.Ringtone={file:"Ringtone_1.mp3",url:hostingPrefex+"sounds/Ringtone_1.mp3"},audioBlobs.speaker_test={file:"Speaker_test.mp3",url:hostingPrefex+"sounds/Speaker_test.mp3"},audioBlobs.Busy_UK={file:"Tone_Busy-UK.mp3",url:hostingPrefex+"sounds/Tone_Busy-UK.mp3"},audioBlobs.Busy_US={file:"Tone_Busy-US.mp3",url:hostingPrefex+"sounds/Tone_Busy-US.mp3"},audioBlobs.CallWaiting={file:"Tone_CallWaiting.mp3",url:hostingPrefex+"sounds/Tone_CallWaiting.mp3"},audioBlobs.Congestion_UK={file:"Tone_Congestion-UK.mp3",url:hostingPrefex+"sounds/Tone_Congestion-UK.mp3"},audioBlobs.Congestion_US={file:"Tone_Congestion-US.mp3",url:hostingPrefex+"sounds/Tone_Congestion-US.mp3"},audioBlobs.EarlyMedia_Australia={file:"Tone_EarlyMedia-Australia.mp3",url:hostingPrefex+"sounds/Tone_EarlyMedia-Australia.mp3"},audioBlobs.EarlyMedia_European={file:"Tone_EarlyMedia-European.mp3",url:hostingPrefex+"sounds/Tone_EarlyMedia-European.mp3"},audioBlobs.EarlyMedia_Japan={file:"Tone_EarlyMedia-Japan.mp3",url:hostingPrefex+"sounds/Tone_EarlyMedia-Japan.mp3"},audioBlobs.EarlyMedia_UK={file:"Tone_EarlyMedia-UK.mp3",url:hostingPrefex+"sounds/Tone_EarlyMedia-UK.mp3"},audioBlobs.EarlyMedia_US={file:"Tone_EarlyMedia-US.mp3",url:hostingPrefex+"sounds/Tone_EarlyMedia-US.mp3"},$.each(audioBlobs,(function(e,t){var i=new XMLHttpRequest;i.open("GET",t.url,!0),i.responseType="blob",i.onload=function(e){var n=new FileReader;n.readAsDataURL(i.response),n.onload=function(){t.blob=n.result}},i.send()}))}function CreateUserAgent(){$.ajax({async:!1,global:!1,type:"POST",url:"get-sippass.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(e){decSipPass=e},error:function(e){alert("An error occurred while attempting to retrieve data from the database!")}});try{console.log("Creating User Agent...");var e={displayName:profileName,uri:SipUsername+"@"+wssServer,transportOptions:{wsServers:"wss://"+wssServer+":"+WebSocketPort+ServerPath,traceSip:!1,connectionTimeout:TransportConnectionTimeout,maxReconnectionAttempts:TransportReconnectionAttempts,reconnectionTimeout:TransportReconnectionTimeout},sessionDescriptionHandlerFactoryOptions:{peerConnectionOptions:{alwaysAcquireMediaFirst:!0,iceCheckingTimeout:IceStunCheckTimeout,rtcConfiguration:{}}},authorizationUser:SipUsername,password:decSipPass,registerExpires:RegisterExpires,hackWssInTransport:WssInTransport,hackIpInContact:IpInContact,userAgentString:userAgentStr,autostart:!1,register:!1};decSipPass="";var t=getDbItem("StunServer","");if(""==t||null==t||void 0===t)var i="";else i='[{"urls":"stun:'+t+'"}]';""!=i&&(e.sessionDescriptionHandlerFactoryOptions.peerConnectionOptions.rtcConfiguration.iceServers=JSON.parse(i)),userAgent=new SIP.UA(e),console.log("Creating User Agent... Done")}catch(e){return console.error("Error creating User Agent: "+e),$("#regStatus").html(lang.error_user_agant),void alert(e.message)}userAgent.on("registered",(function(){isReRegister||(console.log("Registered!"),$("#reglink").hide(),$("#dereglink").show(),(DoNotDisturbEnabled||"enabled"==DoNotDisturbPolicy)&&$("#dereglink").attr("class","dotDoNotDisturb"),SubscribeAll(),$("#regStatus").html(lang.registered),"undefined"!=typeof web_hook_on_register&&web_hook_on_register(userAgent)),isReRegister=!0})),userAgent.on("registrationFailed",(function(e,t){console.log("Registration Failed: "+t),$("#regStatus").html(lang.registration_failed),$("#reglink").show(),$("#dereglink").hide(),isReRegister=!1,"undefined"!=typeof web_hook_on_registrationFailed&&web_hook_on_registrationFailed(t)})),userAgent.on("unregistered",(function(){console.log("Unregistered, bye!"),$("#regStatus").html(lang.unregistered),$("#reglink").show(),$("#dereglink").hide(),"undefined"!=typeof web_hook_on_unregistered&&web_hook_on_unregistered()})),userAgent.on("transportCreated",(function(e){console.log("Transport Object Created"),e.on("connected",(function(){console.log("Connected to Web Socket!"),$("#regStatus").html(lang.connected_to_web_socket),$("#WebRtcFailed").hide(),window.setTimeout((function(){Register()}),500)})),e.on("disconnected",(function(){console.log("Disconnected from Web Socket!"),$("#regStatus").html(lang.disconnected_from_web_socket),isReRegister=!1})),e.on("transportError",(function(){console.log("Web Socket error!"),$("#regStatus").html(lang.web_socket_error),$("#WebRtcFailed").show(),"undefined"!=typeof web_hook_on_transportError&&web_hook_on_transportError(e,userAgent)}))})),userAgent.on("invite",(function(e){ReceiveCall(e),1==getDbItem("Notifications","")&&incomingCallNote(),changePageTitle(),"undefined"!=typeof web_hook_on_invite&&web_hook_on_invite(e)})),userAgent.on("message",(function(e){ReceiveMessage(e),"undefined"!=typeof web_hook_on_message&&web_hook_on_message(e)})),console.log("Connecting to Web Socket..."),$("#regStatus").html(lang.connecting_to_web_socket),userAgent.start(),$("#reglink").on("click",Register),$("#WebRtcFailed").on("click",(function(){Confirm(lang.error_connecting_web_socket,lang.web_socket_error,(function(){window.open("https://"+wssServer+":"+WebSocketPort+"/httpstatus")}),null)}))}function Register(){null==userAgent||userAgent.isRegistered()||(console.log("Sending Registration..."),$("#regStatus").html(lang.sending_registration),userAgent.register(),1==getDbItem("Notifications","")&&"granted"!=Notification.permission&&Notification.requestPermission())}function Unregister(){if(null!=userAgent&&userAgent.isRegistered()){console.log("Unsubscribing..."),$("#regStatus").html(lang.unsubscribing);try{UnsubscribeAll()}catch(e){}console.log("Disconnecting..."),$("#regStatus").html(lang.disconnecting),userAgent.unregister(),isReRegister=!1}}function ReceiveCall(e){var t=e.remoteIdentity.displayName,i=e.remoteIdentity.uri.user;void 0===t&&(t=""),console.log("New Incoming Call!",t+" <"+i+">");var n=countSessions(e.id);console.log("Current Call Count:",n);var a=FindBuddyByDid(i);if(null==a){var o=i.length>DidLength?"contact":"extension";a=MakeBuddy(o,!0,0==n,!0,t,i)}else("extension"==a.type&&a.CallerIDName!=t||"contact"==a.type&&t!=i&&a.CallerIDName!=t)&&UpdateBuddyCalerID(a,t);var l=a.identity;window.clearInterval(e.data.callTimer);var s=moment.utc();e.data.callstart=s.format("YYYY-MM-DD HH:mm:ss UTC"),$("#contact-"+l+"-timer").show(),e.data.callTimer=window.setInterval((function(){var e=moment.utc(),t=moment.duration(e.diff(s));$("#contact-"+l+"-timer").html(formatShortDuration(t.asSeconds()))}),1e3),e.data.buddyId=l,e.data.calldirection="inbound",e.data.terminateby="them",e.data.withvideo=!1;var r,d=!1;if(e.request.body&&e.request.body.indexOf("m=video")>-1&&(d=!0,"contact"==a.type&&(d=!1)),e.on("rejected",(function(t,i){console.log("Call rejected: "+i),e.data.reasonCode=t.status_code,e.data.reasonText=i,AddCallMessage(l,e,t.status_code,i),"undefined"!=typeof web_hook_on_terminate&&web_hook_on_terminate(e)})),e.on("terminated",(function(t,i){e.data.rinngerObj&&(e.data.rinngerObj.pause(),e.data.rinngerObj.removeAttribute("src"),e.data.rinngerObj.load(),e.data.rinngerObj=null),$.jeegoopopup.close(),console.log("Call terminated"),window.clearInterval(e.data.callTimer),$("#contact-"+l+"-timer").html(""),$("#contact-"+l+"-timer").hide(),$("#contact-"+l+"-msg").html(""),$("#contact-"+l+"-msg").hide(),$("#contact-"+l+"-AnswerCall").hide(),RefreshStream(a),updateScroll(a.identity),UpdateBuddyList()})),DoNotDisturbEnabled||"enabled"==DoNotDisturbPolicy)return console.log("Do Not Disturb Enabled, rejecting call."),void RejectCall(a.identity);if(n>=1&&(0==CallWaitingEnabled||"disabled"==CallWaitingEnabled))return console.log("Call Waiting Disabled, rejecting call."),void RejectCall(a.identity);if(AutoAnswerEnabled||"enabled"==AutoAnswerPolicy){if(0==n){console.log("Auto Answer Call...");var c=a.identity;return window.setTimeout((function(){d?AnswerVideoCall(c):AnswerAudioCall(c)}),1e3),void SelectBuddy(a.identity)}console.warn("Could not auto answer call, already on a call.")}($("#contact-"+a.identity+"-msg").html(lang.incomming_call_from+" "+t+" <"+i+">"),$("#contact-"+a.identity+"-msg").show(),d?$("#contact-"+a.identity+"-answer-video").show():$("#contact-"+a.identity+"-answer-video").hide(),$("#contact-"+a.identity+"-AnswerCall").show(),updateScroll(a.identity),n>=1)?(console.log("Audio:",audioBlobs.CallWaiting.url),(r=new Audio(audioBlobs.CallWaiting.blob)).preload="auto",r.loop=!1,r.oncanplaythrough=function(e){void 0!==r.sinkId&&"default"!=getRingerOutputID()&&r.setSinkId(getRingerOutputID()).then((function(){console.log("Set sinkId to:",getRingerOutputID())})).catch((function(e){console.warn("Failed not apply setSinkId.",e)})),r.play().then((function(){})).catch((function(e){console.warn("Unable to play audio file.",e)}))},e.data.rinngerObj=r):(console.log("Audio:",audioBlobs.Ringtone.url),(r=new Audio(audioBlobs.Ringtone.blob)).preload="auto",r.loop=!0,r.oncanplaythrough=function(e){void 0!==r.sinkId&&"default"!=getRingerOutputID()&&r.setSinkId(getRingerOutputID()).then((function(){console.log("Set sinkId to:",getRingerOutputID())})).catch((function(e){console.warn("Failed not apply setSinkId.",e)})),r.play().then((function(){})).catch((function(e){console.warn("Unable to play audio file.",e)}))},e.data.rinngerObj=r);$.jeegoopopup.close();var u='<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>';if(u+='<div class="UiWindowField scroller" style="text-align:center">',u+='<div style="font-size: 18px; margin-top:1px">'+t+"<div>",t!=i&&(u+='<div style="font-size: 18px; margin-top:1px"><'+i+"><div>"),u+='<div class=callAnswerBuddyIcon style="background-image: url('+getPicture(a.identity)+'); margin-top:6px"></div>',u+='<div style="margin-top:14px"><button onclick="AnswerAudioCall(\''+a.identity+'\')" class=answerButton><i class="fa fa-phone"></i> '+lang.answer_call+"</button></div>",d&&(u+='<div style="margin-top:11px"><button onclick="AnswerVideoCall(\''+a.identity+'\')" class=answerButton><i class="fa fa-video-camera"></i> '+lang.answer_call_with_video+"</button></div>"),u+='<div style="margin-top:11px"><button onclick="RejectCall(\''+a.identity+'\')" class=hangupButton><i class="fa fa-phone"></i> '+lang.reject_call+"</button></div>",u+="</div>",$.jeegoopopup.open({title:"Incoming Call",html:u,width:"290",height:"300",center:!0,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#closeImg").click((function(){$.jeegoopopup.close()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()})),IncreaseMissedBadge(a.identity),"Notification"in window&&1==getDbItem("Notifications","")){var p={body:lang.incomming_call_from+" "+t+' "'+i+'"',icon:getPicture(a.identity)};new Notification(lang.incomming_call,p).onclick=function(e){var t=a.identity;window.setTimeout((function(){d?AnswerVideoCall(t):AnswerAudioCall(t)}),4e3),SelectBuddy(a.identity)}}}function AnswerAudioCall(e){$.jeegoopopup.close();var t=FindBuddyByIdentity(e);if(null==t)return console.warn("Audio Answer failed, null buddy"),$("#contact-"+e+"-msg").html(lang.call_failed),void $("#contact-"+e+"-AnswerCall").hide();var i=getSession(e);if(null==i)return console.warn("Audio Answer failed, null session"),$("#contact-"+e+"-msg").html(lang.call_failed),void $("#contact-"+e+"-AnswerCall").hide();if(i.data.rinngerObj&&(i.data.rinngerObj.pause(),i.data.rinngerObj.removeAttribute("src"),i.data.rinngerObj.load(),i.data.rinngerObj=null),0==HasAudioDevice)return Alert(lang.alert_no_microphone),$("#contact-"+e+"-msg").html(lang.call_failed),void $("#contact-"+e+"-AnswerCall").hide();$("#contact-"+e+"-timer").html(""),$("#contact-"+e+"-timer").hide(),$("#contact-"+e+"-msg").html(""),$("#contact-"+e+"-msg").hide(),$("#contact-"+e+"-AnswerCall").hide();var n=i.remoteIdentity.displayName,a=i.remoteIdentity.uri.user;newLineNumber+=1,lineObj=new Line(newLineNumber,n,a,t),lineObj.SipSession=i,lineObj.SipSession.data.line=lineObj.LineNumber,lineObj.SipSession.data.buddyId=lineObj.BuddyObj.identity,Lines.push(lineObj),AddLineHtml(lineObj),SelectLine(newLineNumber),UpdateBuddyList();var o=navigator.mediaDevices.getSupportedConstraints(),l={sessionDescriptionHandlerOptions:{constraints:{audio:{deviceId:"default"},video:!1}}},s=getAudioSrcID();if("default"!=s){for(var r=!1,d=0;d<AudioinputDevices.length;++d)if(s==AudioinputDevices[d].deviceId){r=!0;break}r?l.sessionDescriptionHandlerOptions.constraints.audio.deviceId={exact:s}:(console.warn("The audio device you used before is no longer available, default settings applied."),localDB.setItem("AudioSrcId","default"))}o.autoGainControl&&(l.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl=AutoGainControl),o.echoCancellation&&(l.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation=EchoCancellation),o.noiseSuppression&&(l.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression=NoiseSuppression),lineObj.SipSession.accept(l),lineObj.SipSession.data.withvideo=!1,lineObj.SipSession.data.VideoSourceDevice=null,lineObj.SipSession.data.AudioSourceDevice=getAudioSrcID(),lineObj.SipSession.data.AudioOutputDevice=getAudioOutputID(),wireupAudioSession(lineObj),$("#contact-"+e+"-msg").html(lang.call_in_progress),$("#contact-"+e+"-AnswerCall").hide()}function AnswerVideoCall(e){$.jeegoopopup.close();var t=FindBuddyByIdentity(e);if(null==t)return console.warn("Audio Answer failed, null buddy"),$("#contact-"+e+"-msg").html(lang.call_failed),void $("#contact-"+e+"-AnswerCall").hide();var i=getSession(e);if(null==i)return console.warn("Video Answer failed, null session"),$("#contact-"+e+"-msg").html(lang.call_failed),void $("#contact-"+e+"-AnswerCall").hide();if(i.data.rinngerObj&&(i.data.rinngerObj.pause(),i.data.rinngerObj.removeAttribute("src"),i.data.rinngerObj.load(),i.data.rinngerObj=null),0==HasAudioDevice)return Alert(lang.alert_no_microphone),$("#contact-"+e+"-msg").html(lang.call_failed),void $("#contact-"+e+"-AnswerCall").hide();if(0==HasVideoDevice)return console.warn("No video devices (webcam) found, switching to audio call."),void AnswerAudioCall(e);$("#contact-"+e+"-timer").html(""),$("#contact-"+e+"-timer").hide(),$("#contact-"+e+"-msg").html(""),$("#contact-"+e+"-msg").hide(),$("#contact-"+e+"-AnswerCall").hide();var n=i.remoteIdentity.displayName,a=i.remoteIdentity.uri.user;newLineNumber+=1,lineObj=new Line(newLineNumber,n,a,t),lineObj.SipSession=i,lineObj.SipSession.data.line=lineObj.LineNumber,lineObj.SipSession.data.buddyId=lineObj.BuddyObj.identity,Lines.push(lineObj),AddLineHtml(lineObj),SelectLine(newLineNumber),UpdateBuddyList();var o=navigator.mediaDevices.getSupportedConstraints(),l={sessionDescriptionHandlerOptions:{constraints:{audio:{deviceId:"default"},video:{deviceId:"default"}}}},s=getAudioSrcID();if("default"!=s){for(var r=!1,d=0;d<AudioinputDevices.length;++d)if(s==AudioinputDevices[d].deviceId){r=!0;break}r?l.sessionDescriptionHandlerOptions.constraints.audio.deviceId={exact:s}:(console.warn("The audio device you used before is no longer available, default settings applied."),localDB.setItem("AudioSrcId","default"))}o.autoGainControl&&(l.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl=AutoGainControl),o.echoCancellation&&(l.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation=EchoCancellation),o.noiseSuppression&&(l.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression=NoiseSuppression);var c=getVideoSrcID();if("default"!=c){var u=!1;for(d=0;d<VideoinputDevices.length;++d)if(c==VideoinputDevices[d].deviceId){u=!0;break}u?l.sessionDescriptionHandlerOptions.constraints.video.deviceId={exact:c}:(console.warn("The video device you used before is no longer available, default settings applied."),localDB.setItem("VideoSrcId","default"))}o.frameRate&&""!=maxFrameRate&&(l.sessionDescriptionHandlerOptions.constraints.video.frameRate=maxFrameRate),o.height&&""!=videoHeight&&(l.sessionDescriptionHandlerOptions.constraints.video.height=videoHeight),o.aspectRatio&&""!=videoAspectRatio&&(l.sessionDescriptionHandlerOptions.constraints.video.aspectRatio=videoAspectRatio),lineObj.SipSession.data.withvideo=!0,lineObj.SipSession.data.VideoSourceDevice=getVideoSrcID(),lineObj.SipSession.data.AudioSourceDevice=getAudioSrcID(),lineObj.SipSession.data.AudioOutputDevice=getAudioOutputID(),$("#contact-"+e+"-msg").html(lang.call_in_progress),wireupVideoSession(lineObj);try{lineObj.SipSession.accept(l),StartVideoFullScreen&&ExpandVideoArea(lineObj.LineNumber),$("#contact-"+e+"-AnswerCall").hide()}catch(e){console.warn("Failed to answer call",e,lineObj.SipSession),teardownSession(lineObj,500,"Client Error")}}function RejectCall(e){var t=getSession(e);null==t&&(console.warn("Reject failed, null session"),$("#contact-"+e+"-msg").html(lang.call_failed),$("#contact-"+e+"-AnswerCall").hide()),t.data.terminateby="us",t.reject({statusCode:486,reasonPhrase:"Rejected by us"}),$("#contact-"+e+"-msg").html(lang.call_rejected)}function wireupAudioSession(e){if(null!=e){var t="#line-"+e.LineNumber+"-msg",i=e.SipSession;i.on("progress",(function(e){if(100==e.status_code)$(t).html(lang.trying);else if(180==e.status_code){$(t).html(lang.ringing);var n=audioBlobs.EarlyMedia_European;UserLocale().indexOf("us")>-1&&(n=audioBlobs.EarlyMedia_US),UserLocale().indexOf("gb")>-1&&(n=audioBlobs.EarlyMedia_UK),UserLocale().indexOf("au")>-1&&(n=audioBlobs.EarlyMedia_Australia),UserLocale().indexOf("jp")>-1&&(n=audioBlobs.EarlyMedia_Japan),console.log("Audio:",n.url);var a=new Audio(n.blob);a.preload="auto",a.loop=!0,a.oncanplaythrough=function(e){void 0!==a.sinkId&&"default"!=getAudioOutputID()&&a.setSinkId(getAudioOutputID()).then((function(){console.log("Set sinkId to:",getAudioOutputID())})).catch((function(e){console.warn("Failed not apply setSinkId.",e)})),a.play().then((function(){})).catch((function(e){console.warn("Unable to play audio file.",e)}))},i.data.earlyMedia=a}else $(t).html(e.reason_phrase+"...");"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("progress",i)})),i.on("trackAdded",(function(){var t=i.sessionDescriptionHandler.peerConnection,n=new MediaStream;t.getReceivers().forEach((function(e){e.track&&"audio"==e.track.kind&&n.addTrack(e.track)}));var a=$("#line-"+e.LineNumber+"-remoteAudio").get(0);a.srcObject=n,a.onloadedmetadata=function(e){void 0!==a.sinkId&&a.setSinkId(getAudioOutputID()).then((function(){console.log("sinkId applied: "+getAudioOutputID())})).catch((function(e){console.warn("Error using setSinkId: ",e)})),a.play()},"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("trackAdded",i)})),i.on("accepted",(function(n){i.data.earlyMedia&&(i.data.earlyMedia.pause(),i.data.earlyMedia.removeAttribute("src"),i.data.earlyMedia.load(),i.data.earlyMedia=null),window.clearInterval(i.data.callTimer);var a=moment.utc();i.data.callTimer=window.setInterval((function(){var t=moment.utc(),i=moment.duration(t.diff(a));$("#line-"+e.LineNumber+"-timer").html(formatShortDuration(i.asSeconds()))}),1e3),(RecordAllCalls||"enabled"==CallRecordingPolicy)&&StartRecording(e.LineNumber),$("#line-"+e.LineNumber+"-progress").hide(),$("#line-"+e.LineNumber+"-VideoCall").hide(),$("#line-"+e.LineNumber+"-ActiveCall").show(),e.LocalSoundMeter=StartLocalAudioMediaMonitoring(e.LineNumber,i),e.RemoteSoundMeter=StartRemoteAudioMediaMonitoring(e.LineNumber,i),$(t).html(lang.call_in_progress),updateLineScroll(e.LineNumber),UpdateBuddyList(),"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("accepted",i)})),i.on("rejected",(function(i,n){$(t).html(lang.call_rejected+": "+n),console.log("Call rejected: "+n),teardownSession(e,i.status_code,i.reason_phrase)})),i.on("failed",(function(i,n){$(t).html(lang.call_failed+": "+n),console.log("Call failed: "+n),teardownSession(e,0,"Call failed")})),i.on("cancel",(function(){$(t).html(lang.call_cancelled),console.log("Call Cancelled"),teardownSession(e,0,"Cancelled by caller")})),i.on("bye",(function(){$(t).html(lang.call_ended),console.log("Call ended, bye!"),teardownSession(e,16,"Normal Call clearing")})),i.on("terminated",(function(i,n){$(t).html(lang.call_ended),console.log("Session terminated"),teardownSession(e,16,"Normal Call clearing")})),i.on("reinvite",(function(e){console.log("Session reinvited!")})),i.on("directionChanged",(function(){var e=i.sessionDescriptionHandler.getDirection();console.log("Direction Change: ",e),"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("directionChanged",i)})),$("#line-"+e.LineNumber+"-btn-settings").removeAttr("disabled"),$("#line-"+e.LineNumber+"-btn-audioCall").prop("disabled","disabled"),$("#line-"+e.LineNumber+"-btn-videoCall").prop("disabled","disabled"),$("#line-"+e.LineNumber+"-btn-search").removeAttr("disabled"),$("#line-"+e.LineNumber+"-btn-remove").prop("disabled","disabled"),$("#line-"+e.LineNumber+"-progress").show(),$("#line-"+e.LineNumber+"-msg").show(),"group"==e.BuddyObj.type?$("#line-"+e.LineNumber+"-conference").show():$("#line-"+e.LineNumber+"-conference").hide(),updateLineScroll(e.LineNumber),UpdateUI()}}function wireupVideoSession(e){if(null!=e){var t="#line-"+e.LineNumber+"-msg",i=e.SipSession;i.on("trackAdded",(function(){var t=i.sessionDescriptionHandler.peerConnection,n=new MediaStream,a=new MediaStream;if(t.getReceivers().forEach((function(e){e.track&&("audio"==e.track.kind&&n.addTrack(e.track),"video"==e.track.kind&&a.addTrack(e.track))})),n.getAudioTracks().length>=1){var o=$("#line-"+e.LineNumber+"-remoteAudio").get(0);o.srcObject=n,o.onloadedmetadata=function(e){void 0!==o.sinkId&&o.setSinkId(getAudioOutputID()).then((function(){console.log("sinkId applied: "+getAudioOutputID())})).catch((function(e){console.warn("Error using setSinkId: ",e)})),o.play()}}if(a.getVideoTracks().length>=1){var l=$("#line-"+e.LineNumber+"-remoteVideo").get(0);l.srcObject=a,l.onloadedmetadata=function(e){l.play()}}window.setTimeout((function(){var t=new MediaStream;i.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(e){e.track&&"video"==e.track.kind&&t.addTrack(e.track)}));var n=$("#line-"+e.LineNumber+"-localVideo").get(0);n.srcObject=t,n.onloadedmetadata=function(e){n.play()}}),1e3),"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("trackAdded",i)})),i.on("progress",(function(e){if(100==e.status_code)$(t).html(lang.trying);else if(180==e.status_code){$(t).html(lang.ringing);var n=audioBlobs.EarlyMedia_European;UserLocale().indexOf("us")>-1&&(n=audioBlobs.EarlyMedia_US),UserLocale().indexOf("gb")>-1&&(n=audioBlobs.EarlyMedia_UK),UserLocale().indexOf("au")>-1&&(n=audioBlobs.EarlyMedia_Australia),UserLocale().indexOf("jp")>-1&&(n=audioBlobs.EarlyMedia_Japan),console.log("Audio:",n.url);var a=new Audio(n.blob);a.preload="auto",a.loop=!0,a.oncanplaythrough=function(e){void 0!==a.sinkId&&"default"!=getAudioOutputID()&&a.setSinkId(getAudioOutputID()).then((function(){console.log("Set sinkId to:",getAudioOutputID())})).catch((function(e){console.warn("Failed not apply setSinkId.",e)})),a.play().then((function(){})).catch((function(e){console.warn("Unable to play audio file.",e)}))},i.data.earlyMedia=a}else $(t).html(e.reason_phrase+"...");"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("progress",i)})),i.on("accepted",(function(n){i.data.earlyMedia&&(i.data.earlyMedia.pause(),i.data.earlyMedia.removeAttribute("src"),i.data.earlyMedia.load(),i.data.earlyMedia=null),window.clearInterval(i.data.callTimer),$("#line-"+e.LineNumber+"-timer").show();var a=moment.utc();i.data.callTimer=window.setInterval((function(){var t=moment.utc(),i=moment.duration(t.diff(a));$("#line-"+e.LineNumber+"-timer").html(formatShortDuration(i.asSeconds()))}),1e3),(RecordAllCalls||"enabled"==CallRecordingPolicy)&&StartRecording(e.LineNumber),$("#line-"+e.LineNumber+"-progress").hide(),$("#line-"+e.LineNumber+"-VideoCall").show(),$("#line-"+e.LineNumber+"-ActiveCall").show(),$("#line-"+e.LineNumber+"-btn-Conference").hide(),$("#line-"+e.LineNumber+"-btn-CancelConference").hide(),$("#line-"+e.LineNumber+"-Conference").hide(),$("#line-"+e.LineNumber+"-btn-Transfer").hide(),$("#line-"+e.LineNumber+"-btn-CancelTransfer").hide(),$("#line-"+e.LineNumber+"-Transfer").hide(),$("#line-"+e.LineNumber+"-src-camera").prop("disabled",!0),$("#line-"+e.LineNumber+"-src-canvas").prop("disabled",!1),$("#line-"+e.LineNumber+"-src-desktop").prop("disabled",!1),$("#line-"+e.LineNumber+"-src-video").prop("disabled",!1),updateLineScroll(e.LineNumber),e.LocalSoundMeter=StartLocalAudioMediaMonitoring(e.LineNumber,i),e.RemoteSoundMeter=StartRemoteAudioMediaMonitoring(e.LineNumber,i),$(t).html(lang.call_in_progress),StartVideoFullScreen&&ExpandVideoArea(e.LineNumber),"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("accepted",i)})),i.on("rejected",(function(i,n){$(t).html(lang.call_rejected+": "+n),console.log("Call rejected: "+n),teardownSession(e,i.status_code,i.reason_phrase)})),i.on("failed",(function(i,n){$(t).html(lang.call_failed+": "+n),console.log("Call failed: "+n),teardownSession(e,0,"call failed")})),i.on("cancel",(function(){$(t).html(lang.call_cancelled),console.log("Call Cancelled"),teardownSession(e,0,"Cancelled by caller")})),i.on("bye",(function(){$(t).html(lang.call_ended),console.log("Call ended, bye!"),teardownSession(e,16,"Normal Call clearing")})),i.on("terminated",(function(i,n){$(t).html(lang.call_ended),console.log("Session terminated"),teardownSession(e,16,"Normal Call clearing")})),i.on("reinvite",(function(e){console.log("Session reinvited!")})),i.on("directionChanged",(function(){var e=i.sessionDescriptionHandler.getDirection();console.log("Direction Change: ",e),"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("directionChanged",i)})),$("#line-"+e.LineNumber+"-btn-settings").removeAttr("disabled"),$("#line-"+e.LineNumber+"-btn-audioCall").prop("disabled","disabled"),$("#line-"+e.LineNumber+"-btn-videoCall").prop("disabled","disabled"),$("#line-"+e.LineNumber+"-btn-search").removeAttr("disabled"),$("#line-"+e.LineNumber+"-btn-remove").prop("disabled","disabled"),$("#line-"+e.LineNumber+"-progress").show(),$("#line-"+e.LineNumber+"-msg").show(),updateLineScroll(e.LineNumber),UpdateUI()}}function teardownSession(e,t,i){if(null!=e&&null!=e.SipSession){var n=e.SipSession;if(1!=n.data.teardownComplete){if(n.data.teardownComplete=!0,n.data.reasonCode=t,n.data.reasonText=i,$.jeegoopopup.close(),n.data.childsession)try{n.data.childsession.status==SIP.Session.C.STATUS_CONFIRMED?n.data.childsession.bye():n.data.childsession.cancel()}catch(e){}n.data.childsession=null,n.data.AudioSourceTrack&&"audio"==n.data.AudioSourceTrack.kind&&(n.data.AudioSourceTrack.stop(),n.data.AudioSourceTrack=null),n.data.earlyMedia&&(n.data.earlyMedia.pause(),n.data.earlyMedia.removeAttribute("src"),n.data.earlyMedia.load(),n.data.earlyMedia=null),StopRecording(e.LineNumber,!0),null!=e.LocalSoundMeter&&(e.LocalSoundMeter.stop(),e.LocalSoundMeter=null),null!=e.RemoteSoundMeter&&(e.RemoteSoundMeter.stop(),e.RemoteSoundMeter=null),window.clearInterval(n.data.videoResampleInterval),window.clearInterval(n.data.callTimer),AddCallMessage(e.BuddyObj.identity,n,t,i),window.setTimeout((function(){RemoveLine(e)}),1e3),UpdateBuddyList(),UpdateUI(),"undefined"!=typeof web_hook_on_terminate&&web_hook_on_terminate(n)}}}function StartRemoteAudioMediaMonitoring(e,t){console.log("Creating RemoteAudio AudioContext on Line:"+e);var i=new SoundMeter(t.id,e);if(null==i)return console.warn("AudioContext() RemoteAudio not available... it fine."),null;var n=new MediaStream,a=null;t.sessionDescriptionHandler.peerConnection.getReceivers().forEach((function(e){e.track&&"audio"==e.track.kind&&(null==a?(n.addTrack(e.track),a=e):(console.log("Found another Track, but audioReceiver not null"),console.log(e),console.log(e.track)))}));i.startTime=Date.now(),Chart.defaults.global.defaultFontSize=12;var o={responsive:!1,maintainAspectRatio:!1,devicePixelRatio:1,animation:!1,scales:{yAxes:[{ticks:{beginAtZero:!0}}]}};return i.ReceiveBitRateChart=new Chart($("#line-"+e+"-AudioReceiveBitRate"),{type:"line",data:{labels:MakeDataArray("",100),datasets:[{label:lang.receive_kilobits_per_second,data:MakeDataArray(0,100),backgroundColor:"rgba(168, 0, 0, 0.5)",borderColor:"rgba(168, 0, 0, 1)",borderWidth:1,pointRadius:1}]},options:o}),i.ReceiveBitRateChart.lastValueBytesReceived=0,i.ReceiveBitRateChart.lastValueTimestamp=0,i.ReceivePacketRateChart=new Chart($("#line-"+e+"-AudioReceivePacketRate"),{type:"line",data:{labels:MakeDataArray("",100),datasets:[{label:lang.receive_packets_per_second,data:MakeDataArray(0,100),backgroundColor:"rgba(168, 0, 0, 0.5)",borderColor:"rgba(168, 0, 0, 1)",borderWidth:1,pointRadius:1}]},options:o}),i.ReceivePacketRateChart.lastValuePacketReceived=0,i.ReceivePacketRateChart.lastValueTimestamp=0,i.ReceivePacketLossChart=new Chart($("#line-"+e+"-AudioReceivePacketLoss"),{type:"line",data:{labels:MakeDataArray("",100),datasets:[{label:lang.receive_packet_loss,data:MakeDataArray(0,100),backgroundColor:"rgba(168, 99, 0, 0.5)",borderColor:"rgba(168, 99, 0, 1)",borderWidth:1,pointRadius:1}]},options:o}),i.ReceivePacketLossChart.lastValuePacketLoss=0,i.ReceivePacketLossChart.lastValueTimestamp=0,i.ReceiveJitterChart=new Chart($("#line-"+e+"-AudioReceiveJitter"),{type:"line",data:{labels:MakeDataArray("",100),datasets:[{label:lang.receive_jitter,data:MakeDataArray(0,100),backgroundColor:"rgba(0, 38, 168, 0.5)",borderColor:"rgba(0, 38, 168, 1)",borderWidth:1,pointRadius:1}]},options:o}),i.ReceiveLevelsChart=new Chart($("#line-"+e+"-AudioReceiveLevels"),{type:"line",data:{labels:MakeDataArray("",100),datasets:[{label:lang.receive_audio_levels,data:MakeDataArray(0,100),backgroundColor:"rgba(140, 0, 168, 0.5)",borderColor:"rgba(140, 0, 168, 1)",borderWidth:1,pointRadius:1}]},options:o}),i.connectToSource(n,(function(t){null==t&&(console.log("SoundMeter for RemoteAudio Connected, displaying levels for Line: "+e),i.levelsInterval=window.setInterval((function(){var t=4*i.instant;t>1&&(t=1);var n=100*t;$("#line-"+e+"-Speaker").css("height",n.toFixed(2)+"%")}),50),i.networkInterval=window.setInterval((function(){null!=a&&a.getStats().then((function(e){e.forEach((function(e){var t=utcDateNow(),n=i.ReceiveBitRateChart,a=i.ReceivePacketRateChart,o=i.ReceivePacketLossChart,l=i.ReceiveJitterChart,s=i.ReceiveLevelsChart;Math.floor((Date.now()-i.startTime)/1e3);if("inbound-rtp"==e.type){if(0==n.lastValueTimestamp)return n.lastValueTimestamp=e.timestamp,n.lastValueBytesReceived=e.bytesReceived,a.lastValueTimestamp=e.timestamp,a.lastValuePacketReceived=e.packetsReceived,o.lastValueTimestamp=e.timestamp,void(o.lastValuePacketLoss=e.packetsLost);var r=8*(e.bytesReceived-n.lastValueBytesReceived)/1e3;n.lastValueTimestamp=e.timestamp,n.lastValueBytesReceived=e.bytesReceived,i.ReceiveBitRate.push({value:r,timestamp:t}),n.data.datasets[0].data.push(r),n.data.labels.push(""),n.data.datasets[0].data.length>100&&(n.data.datasets[0].data.splice(0,1),n.data.labels.splice(0,1)),n.update();var d=e.packetsReceived-a.lastValuePacketReceived;a.lastValueTimestamp=e.timestamp,a.lastValuePacketReceived=e.packetsReceived,i.ReceivePacketRate.push({value:d,timestamp:t}),a.data.datasets[0].data.push(d),a.data.labels.push(""),a.data.datasets[0].data.length>100&&(a.data.datasets[0].data.splice(0,1),a.data.labels.splice(0,1)),a.update();var c=e.packetsLost-o.lastValuePacketLoss;o.lastValueTimestamp=e.timestamp,o.lastValuePacketLoss=e.packetsLost,i.ReceivePacketLoss.push({value:c,timestamp:t}),o.data.datasets[0].data.push(c),o.data.labels.push(""),o.data.datasets[0].data.length>100&&(o.data.datasets[0].data.splice(0,1),o.data.labels.splice(0,1)),o.update(),i.ReceiveJitter.push({value:e.jitter,timestamp:t}),l.data.datasets[0].data.push(e.jitter),l.data.labels.push(""),l.data.datasets[0].data.length>100&&(l.data.datasets[0].data.splice(0,1),l.data.labels.splice(0,1)),l.update()}if("track"==e.type){var u=100*e.audioLevel;i.ReceiveLevels.push({value:u,timestamp:t}),s.data.datasets[0].data.push(u),s.data.labels.push(""),s.data.datasets[0].data.length>100&&(s.data.datasets[0].data.splice(0,1),s.data.labels.splice(0,1)),s.update()}}))}))}),1e3))})),i}function StartLocalAudioMediaMonitoring(e,t){console.log("Creating LocalAudio AudioContext on line "+e);var i=new SoundMeter(t.id,e);if(null==i)return console.warn("AudioContext() LocalAudio not available... its fine."),null;var n=new MediaStream,a=null;t.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(e){e.track&&"audio"==e.track.kind&&(null==a?(console.log("Adding Track to Monitor: ",e.track.label),n.addTrack(e.track),a=e):(console.log("Found another Track, but audioSender not null"),console.log(e),console.log(e.track)))}));i.startTime=Date.now(),Chart.defaults.global.defaultFontSize=12;var o={responsive:!1,maintainAspectRatio:!1,devicePixelRatio:1,animation:!1,scales:{yAxes:[{ticks:{beginAtZero:!0}}]}};return i.SendBitRateChart=new Chart($("#line-"+e+"-AudioSendBitRate"),{type:"line",data:{labels:MakeDataArray("",100),datasets:[{label:lang.send_kilobits_per_second,data:MakeDataArray(0,100),backgroundColor:"rgba(0, 121, 19, 0.5)",borderColor:"rgba(0, 121, 19, 1)",borderWidth:1,pointRadius:1}]},options:o}),i.SendBitRateChart.lastValueBytesSent=0,i.SendBitRateChart.lastValueTimestamp=0,i.SendPacketRateChart=new Chart($("#line-"+e+"-AudioSendPacketRate"),{type:"line",data:{labels:MakeDataArray("",100),datasets:[{label:lang.send_packets_per_second,data:MakeDataArray(0,100),backgroundColor:"rgba(0, 121, 19, 0.5)",borderColor:"rgba(0, 121, 19, 1)",borderWidth:1,pointRadius:1}]},options:o}),i.SendPacketRateChart.lastValuePacketSent=0,i.SendPacketRateChart.lastValueTimestamp=0,i.connectToSource(n,(function(t){null==t&&(console.log("SoundMeter for LocalAudio Connected, displaying levels for Line: "+e),i.levelsInterval=window.setInterval((function(){var t=4*i.instant;t>1&&(t=1);var n=100*t;$("#line-"+e+"-Mic").css("height",n.toFixed(2)+"%")}),50),i.networkInterval=window.setInterval((function(){null!=a&&a.getStats().then((function(e){e.forEach((function(e){var t=utcDateNow(),n=i.SendBitRateChart,a=i.SendPacketRateChart;Math.floor((Date.now()-i.startTime)/1e3);if("outbound-rtp"==e.type){if(0==n.lastValueTimestamp)return n.lastValueTimestamp=e.timestamp,n.lastValueBytesSent=e.bytesSent,a.lastValueTimestamp=e.timestamp,void(a.lastValuePacketSent=e.packetsSent);var o=8*(e.bytesSent-n.lastValueBytesSent)/1e3;n.lastValueTimestamp=e.timestamp,n.lastValueBytesSent=e.bytesSent,i.SendBitRate.push({value:o,timestamp:t}),n.data.datasets[0].data.push(o),n.data.labels.push(""),n.data.datasets[0].data.length>100&&(n.data.datasets[0].data.splice(0,1),n.data.labels.splice(0,1)),n.update();var l=e.packetsSent-a.lastValuePacketSent;a.lastValueTimestamp=e.timestamp,a.lastValuePacketSent=e.packetsSent,i.SendPacketRate.push({value:l,timestamp:t}),a.data.datasets[0].data.push(l),a.data.labels.push(""),a.data.datasets[0].data.length>100&&(a.data.datasets[0].data.splice(0,1),a.data.labels.splice(0,1)),a.update()}e.type}))}))}),1e3))})),i}$(window).on("beforeunload",(function(){Unregister()})),$(window).on("resize",(function(){UpdateUI()})),$(document).ready((function(){$.getJSON(hostingPrefex+"lang/en.json",(function(e){lang=e;var t=GetAlternateLanguage();""!=t?$.getJSON(hostingPrefex+"lang/"+t+".json",(function(e){lang=e})).always((function(){console.log("Alternate Lanaguage Pack loaded: ",lang),InitUi()})):(console.log("Lanaguage Pack already loaded: ",lang),InitUi())})),getConfFromSqldb(),getExternalUserConfFromSqldb()}));class SoundMeter{constructor(e,t){var i=null;try{window.AudioContext=window.AudioContext||window.webkitAudioContext,i=new AudioContext}catch(e){console.warn("AudioContext() LocalAudio not available... its fine.")}if(null==i)return null;this.lineNum=t,this.sessionId=e,this.levelsInterval=null,this.networkInterval=null,this.startTime=0,this.ReceiveBitRateChart=null,this.ReceiveBitRate=[],this.ReceivePacketRateChart=null,this.ReceivePacketRate=[],this.ReceivePacketLossChart=null,this.ReceivePacketLoss=[],this.ReceiveJitterChart=null,this.ReceiveJitter=[],this.ReceiveLevelsChart=null,this.ReceiveLevels=[],this.SendBitRateChart=null,this.SendBitRate=[],this.SendPacketRateChart=null,this.SendPacketRate=[],this.context=i,this.instant=0,this.script=i.createScriptProcessor(2048,1,1);const n=this;this.script.onaudioprocess=function(e){const t=e.inputBuffer.getChannelData(0);let i,a=0;for(i=0;i<t.length;++i)a+=t[i]*t[i];n.instant=Math.sqrt(a/t.length)}}connectToSource(e,t){console.log("SoundMeter connecting...");try{this.mic=this.context.createMediaStreamSource(e),this.mic.connect(this.script),this.script.connect(this.context.destination),t(null)}catch(e){console.error(e),t(e)}}stop(){console.log("Disconnecting SoundMeter...");try{window.clearInterval(this.levelsInterval),this.levelsInterval=null}catch(e){}try{window.clearInterval(this.networkInterval),this.networkInterval=null}catch(e){}this.mic.disconnect(),this.script.disconnect(),this.mic=null,this.script=null;try{this.context.close()}catch(e){}this.context=null;var e=FindLineByNumber(this.lineNum);SaveQosData({ReceiveBitRate:this.ReceiveBitRate,ReceivePacketRate:this.ReceivePacketRate,ReceivePacketLoss:this.ReceivePacketLoss,ReceiveJitter:this.ReceiveJitter,ReceiveLevels:this.ReceiveLevels,SendBitRate:this.SendBitRate,SendPacketRate:this.SendPacketRate},this.sessionId,e.BuddyObj.identity)}}function MeterSettingsOutput(e,t,i,n){var a=new SoundMeter(null,null);return a.startTime=Date.now(),a.connectToSource(e,(function(e){null==e&&(console.log("SoundMeter Connected, displaying levels to:"+t),a.levelsInterval=window.setInterval((function(){var e=4*a.instant;e>1&&(e=1);var n=100*e;$("#"+t).css(i,n.toFixed(2)+"%")}),n))})),a}function SaveQosData(e,t,i){var n=window.indexedDB.open("CallQosData");n.onerror=function(e){console.error("IndexDB Request Error:",e)},n.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.");var t=e.target.result;if(0==t.objectStoreNames.contains("CallQos")){var i=t.createObjectStore("CallQos",{keyPath:"uID"});i.createIndex("sessionid","sessionid",{unique:!1}),i.createIndex("buddy","buddy",{unique:!1}),i.createIndex("QosData","QosData",{unique:!1})}else console.warn("IndexDB requested upgrade, but object store was in place")},n.onsuccess=function(n){console.log("IndexDB connected to CallQosData");var a=n.target.result;if(0!=a.objectStoreNames.contains("CallQos")){a.onerror=function(e){console.error("IndexDB Error:",e)};var o={uID:uID(),sessionid:t,buddy:i,QosData:e};a.transaction(["CallQos"],"readwrite").objectStore("CallQos").add(o).onsuccess=function(e){console.log("Call CallQos Sucess: ",t)}}else console.warn("IndexDB CallQosData.CallQos does not exists")}}function DisplayQosData(e){var t=window.indexedDB.open("CallQosData");t.onerror=function(e){console.error("IndexDB Request Error:",e)},t.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.")},t.onsuccess=function(t){console.log("IndexDB connected to CallQosData");var i=t.target.result;if(0!=i.objectStoreNames.contains("CallQos")){var n=i.transaction(["CallQos"]).objectStore("CallQos").index("sessionid").getAll(e);n.onerror=function(e){console.error("IndexDB Get Error:",e)},n.onsuccess=function(e){if(e.target.result&&2==e.target.result.length){var t=e.target.result[0].QosData,i=e.target.result[1].QosData;Chart.defaults.global.defaultFontSize=12;var n={responsive:!0,maintainAspectRatio:!1,animation:!1,scales:{yAxes:[{ticks:{beginAtZero:!0}}],xAxes:[{display:!1}]}},a=[],o=[],l=t.ReceiveBitRate.length>0?t.ReceiveBitRate:i.ReceiveBitRate;$.each(l,(function(e,t){a.push(moment.utc(t.timestamp.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat)),o.push(t.value)}));new Chart($("#cdr-AudioReceiveBitRate"),{type:"line",data:{labels:a,datasets:[{label:lang.receive_kilobits_per_second,data:o,backgroundColor:"rgba(168, 0, 0, 0.5)",borderColor:"rgba(168, 0, 0, 1)",borderWidth:1,pointRadius:1}]},options:n}),a=[],o=[],l=t.ReceivePacketRate.length>0?t.ReceivePacketRate:i.ReceivePacketRate;$.each(l,(function(e,t){a.push(moment.utc(t.timestamp.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat)),o.push(t.value)}));new Chart($("#cdr-AudioReceivePacketRate"),{type:"line",data:{labels:a,datasets:[{label:lang.receive_packets_per_second,data:o,backgroundColor:"rgba(168, 0, 0, 0.5)",borderColor:"rgba(168, 0, 0, 1)",borderWidth:1,pointRadius:1}]},options:n}),a=[],o=[],l=t.ReceivePacketLoss.length>0?t.ReceivePacketLoss:i.ReceivePacketLoss;$.each(l,(function(e,t){a.push(moment.utc(t.timestamp.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat)),o.push(t.value)}));new Chart($("#cdr-AudioReceivePacketLoss"),{type:"line",data:{labels:a,datasets:[{label:lang.receive_packet_loss,data:o,backgroundColor:"rgba(168, 99, 0, 0.5)",borderColor:"rgba(168, 99, 0, 1)",borderWidth:1,pointRadius:1}]},options:n}),a=[],o=[],l=t.ReceiveJitter.length>0?t.ReceiveJitter:i.ReceiveJitter;$.each(l,(function(e,t){a.push(moment.utc(t.timestamp.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat)),o.push(t.value)}));new Chart($("#cdr-AudioReceiveJitter"),{type:"line",data:{labels:a,datasets:[{label:lang.receive_jitter,data:o,backgroundColor:"rgba(0, 38, 168, 0.5)",borderColor:"rgba(0, 38, 168, 1)",borderWidth:1,pointRadius:1}]},options:n}),a=[],o=[],l=t.ReceiveLevels.length>0?t.ReceiveLevels:i.ReceiveLevels;$.each(l,(function(e,t){a.push(moment.utc(t.timestamp.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat)),o.push(t.value)}));new Chart($("#cdr-AudioReceiveLevels"),{type:"line",data:{labels:a,datasets:[{label:lang.receive_audio_levels,data:o,backgroundColor:"rgba(140, 0, 168, 0.5)",borderColor:"rgba(140, 0, 168, 1)",borderWidth:1,pointRadius:1}]},options:n}),a=[],o=[],l=t.SendPacketRate.length>0?t.SendPacketRate:i.SendPacketRate;$.each(l,(function(e,t){a.push(moment.utc(t.timestamp.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat)),o.push(t.value)}));new Chart($("#cdr-AudioSendPacketRate"),{type:"line",data:{labels:a,datasets:[{label:lang.send_packets_per_second,data:o,backgroundColor:"rgba(0, 121, 19, 0.5)",borderColor:"rgba(0, 121, 19, 1)",borderWidth:1,pointRadius:1}]},options:n}),a=[],o=[],l=t.SendBitRate.length>0?t.SendBitRate:i.SendBitRate;$.each(l,(function(e,t){a.push(moment.utc(t.timestamp.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat)),o.push(t.value)}));new Chart($("#cdr-AudioSendBitRate"),{type:"line",data:{labels:a,datasets:[{label:lang.send_kilobits_per_second,data:o,backgroundColor:"rgba(0, 121, 19, 0.5)",borderColor:"rgba(0, 121, 19, 1)",borderWidth:1,pointRadius:1}]},options:n})}else console.warn("Result not expected",e.target.result)}}else console.warn("IndexDB CallQosData.CallQos does not exists")}}function DeleteQosData(e){var t=window.indexedDB.open("CallQosData");t.onerror=function(e){console.error("IndexDB Request Error:",e)},t.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.")},t.onsuccess=function(t){console.log("IndexDB connected to CallQosData");var i=t.target.result;if(0!=i.objectStoreNames.contains("CallQos")){i.onerror=function(e){console.error("IndexDB Error:",e)},console.log("Deleting CallQosData: ",e);var n=i.transaction(["CallQos"],"readwrite").objectStore("CallQos"),a=n.index("buddy").getAll(e);a.onerror=function(e){console.error("IndexDB Get Error:",e)},a.onsuccess=function(e){e.target.result&&e.target.result.length>0&&$.each(e.target.result,(function(e,t){try{n.delete(t.uID)}catch(e){console.log("Call CallQosData Delete failed: ",e)}}))}}else console.warn("IndexDB CallQosData.CallQos does not exists")}}function SubscribeAll(){console.log("Subscribe to voicemail Messages...");(voicemailSubs=userAgent.subscribe(SipUsername+"@"+wssServer,"message-summary",{expires:300})).on("notify",(function(e){var t=!1;$.each(e.request.body.split("\n"),(function(e,i){-1!=i.indexOf("Messages-Waiting:")&&(t="yes"==$.trim(i.replace("Messages-Waiting:","")))})),t&&console.log("You have voicemail!")}));var e={expires:300,extraHeaders:["Accept: application/pidf+xml"]};console.log("Starting Subscribe of all ("+Buddies.length+") Extension Buddies...");for(var t=0;t<Buddies.length;t++){var i=Buddies[t];if("extension"==i.type){console.log("SUBSCRIBE: "+i.ExtNo+"@"+wssServer);var n=userAgent.subscribe(i.ExtNo+"@"+wssServer,"presence",e);n.data.buddyId=i.identity,n.on("notify",(function(e){RecieveBlf(e)})),BlfSubs.push(n)}}}function SubscribeBuddy(e){if("extension"==e.type){console.log("SUBSCRIBE: "+e.ExtNo+"@"+wssServer);var t=userAgent.subscribe(e.ExtNo+"@"+wssServer,"presence",{expires:300,extraHeaders:["Accept: application/pidf+xml"]});t.data.buddyId=e.identity,t.on("notify",(function(e){RecieveBlf(e)})),BlfSubs.push(t)}}function RecieveBlf(e){if(null!=userAgent&&userAgent.isRegistered()){var t=e.request.headers["Content-Type"][0].parsed;if("application/pidf+xml"==t){var i=(l=$($.parseXML(e.request.body))).find("presence").attr("entity"),n=l.find("presence").find("tuple").find("contact").text();if(SipUsername!=i.split("@")[0].split(":")[1]&&SipUsername!=n.split("@")[0].split(":")[1])return void console.warn("presence message not for you.",l);var a=l.find("presence").find("tuple").attr("id"),o=(l.find("presence").find("tuple").find("status"),l.find("presence").find("tuple").find("status").find("basic").text(),"dotOffline");"Not online"==(r=l.find("presence").find("note").text())&&(o="dotOffline"),"Ready"==r&&(o="dotOnline"),"On the phone"==r&&(o="dotInUse"),"Ringing"==r&&(o="dotRinging"),"On hold"==r&&(o="dotOnHold"),"Unavailable"==r&&(o="dotOffline"),null!=(d=FindBuddyByExtNo(a))&&(console.log("Setting Presence for "+d.identity+" to "+r),$("#contact-"+d.identity+"-devstate").prop("class",o),$("#contact-"+d.identity+"-devstate-main").prop("class",o),d.devState=o,d.presence=r,"Not online"==r&&(r=lang.state_not_online),"Ready"==r&&(r=lang.state_ready),"On the phone"==r&&(r=lang.state_on_the_phone),"Ringing"==r&&(r=lang.state_ringing),"On hold"==r&&(r=lang.state_on_hold),"Unavailable"==r&&(r=lang.state_unavailable),$("#contact-"+d.identity+"-presence").html(r),$("#contact-"+d.identity+"-presence-main").html(r))}else if("application/dialog-info+xml"==t){var l;a=(l=$($.parseXML(e.request.body))).find("dialog-info").attr("entity").split("@")[0].split(":")[1],l.find("dialog-info").attr("version");if("full"!=l.find("dialog-info").attr("state"))return;if(l.find("dialog-info").find("dialog").attr("id")!=a)return;var s=l.find("dialog-info").find("dialog").find("state").text(),r="Unknown";"terminated"==s&&(r="Ready"),"trying"==s&&(r="On the phone"),"proceeding"==s&&(r="On the phone"),"early"==s&&(r="Ringing"),"confirmed"==s&&(r="On the phone");var d;o="dotOffline";"Not online"==r&&(o="dotOffline"),"Ready"==r&&(o="dotOnline"),"On the phone"==r&&(o="dotInUse"),"Ringing"==r&&(o="dotRinging"),"On hold"==r&&(o="dotOnHold"),"Unavailable"==r&&(o="dotOffline"),null!=(d=FindBuddyByExtNo(a))&&(console.log("Setting Presence for "+d.identity+" to "+r),$("#contact-"+d.identity+"-devstate").prop("class",o),$("#contact-"+d.identity+"-devstate-main").prop("class",o),d.devState=o,d.presence=r,"Unknown"==r&&(r=lang.state_unknown),"Not online"==r&&(r=lang.state_not_online),"Ready"==r&&(r=lang.state_ready),"On the phone"==r&&(r=lang.state_on_the_phone),"Ringing"==r&&(r=lang.state_ringing),"On hold"==r&&(r=lang.state_on_hold),"Unavailable"==r&&(r=lang.state_unavailable),$("#contact-"+d.identity+"-presence").html(r),$("#contact-"+d.identity+"-presence-main").html(r))}}}function UnsubscribeAll(){console.log("Unsubscribing "+BlfSubs.length+" subscriptions...");for(var e=0;e<BlfSubs.length;e++)BlfSubs[e].unsubscribe(),BlfSubs[e].close();BlfSubs=new Array;for(var t=0;t<Buddies.length;t++){var i=Buddies[t];"extension"==i.type&&($("#contact-"+i.identity+"-devstate").prop("class","dotOffline"),$("#contact-"+i.identity+"-devstate-main").prop("class","dotOffline"),$("#contact-"+i.identity+"-presence").html(lang.state_unknown),$("#contact-"+i.identity+"-presence-main").html(lang.state_unknown))}}function UnsubscribeBuddy(e){if("extension"==e.type)for(var t=0;t<BlfSubs.length;t++){var i=BlfSubs[t];if(i.data.buddyId==e.identity){console.log("Unsubscribing:",e.identity),null!=i.dialog&&(i.unsubscribe(),i.close()),BlfSubs.splice(t,1);break}}}function InitinaliseStream(e){return localDB.setItem(e+"-stream",JSON.stringify({TotalRows:0,DataCollection:[]})),JSON.parse(localDB.getItem(e+"-stream"))}function splitString(e,t){const i=Math.ceil(e.length/t),n=[];for(let a=0,o=0;a<i;++a,o+=t)n[a]=e.substr(o,t);return n}function generateAESKey(e){const t=CryptoJS.lib.WordArray.random(16);return CryptoJS.PBKDF2(e,t,{keySize:8,iterations:100})}function encryptAES(e,t){return(e=CryptoJS.AES.encrypt(e,t)).toString()}function decryptAES(e,t){return CryptoJS.AES.decrypt(e,t).toString(CryptoJS.enc.Utf8)}function getChatRSAPubKey(e){var t="";return $.ajax({async:!1,global:!1,type:"POST",url:"get-text-chat-pub-key.php",dataType:"JSON",data:{recsendsipuser:e,s_ajax_call:validateSToken},success:function(e){"success"==e.resmessage?t="`"+e.chatkey.join("")+"`":(pubKeyCheck=1,alert("An error occurred while retrieving the public key for text chat!"))},error:function(e){alert("An error occurred while attempting to retrieve the public key for text chat!")}}),t}function SendChatMessage(e){if(null!=userAgent&&userAgent.isRegistered()){var t=$("#contact-"+e+"-ChatMessage").val();if(messagetrim=$.trim(t),""!=messagetrim||0!=sendFileCheck&&(1!=sendFileCheck||""!=$("#selectedFile").val())){var i=FindBuddyByIdentity(e);if(-1==$.inArray(i.presence,["Ready","On the phone","Ringing","On hold"]))return alert("You cannot send a message or a file to a contact who is not online!"),$("#sendFileLoader").remove(),$("#selectedFile").val(""),$("#sendFileFormChat").remove(),void(sendFileCheck=0);var n=Date.now()+Math.floor(1e4*Math.random()).toString(6).toUpperCase(),a=String(generateAESKey(n)),o=[],l=(o=splitString(encryptAES(messagetrim,a),900),Date.now()+Math.floor(1e4*Math.random()).toString(16).toUpperCase()+profileUser),s=[];s=[l,1];var r=[];r=[l,0];var d=getChatRSAPubKey(i.ExtNo),c=new JSEncrypt;c.setPublicKey(d);var u=c.encrypt(a);o.unshift(u),$("#contact-"+e+"-ChatHistory").after("<span id='sendFileLoader'></span>");for(var p=0;p<o.length;p++){if(0==p)var g=l+"|"+o.length+"|"+parseInt(p)+"||"+o[p];else if(0==sendFileCheck&&""!=o[p])g=l+"|"+o.length+"|"+parseInt(p)+"||"+o[p];else if(1==sendFileCheck&&""==sendFileChatErr)g=l+"|"+o.length+"|"+parseInt(p)+"|"+upFileName+"|"+o[p];else if(1==sendFileCheck&&""!=sendFileChatErr)return $("#sendFileFormChat").remove(),sendFileChatErr="",void(sendFileCheck=0);1==p&&(s=[l,0]),p==o.length-1&&(r=[l,1]),SendChatMessageProc(e,i,l,g,messagetrim,s,r)}}else Alert(lang.alert_empty_text_message,lang.no_message)}}function SendChatMessageProc(e,t,i,n,a,o,l){var s=uID();if(1==pubKeyCheck)return pubKeyCheck=0,$("#selectedFile").val(""),void $("#sendFileLoader").remove();if(sendFileChatErr="",$("#sendFileFormChat").on("submit",(function(e){e.preventDefault(),$.ajax({async:!1,global:!1,type:"POST",url:"text-chat-upload-file.php",data:new FormData(this),dataType:"JSON",contentType:!1,cache:!1,processData:!1,success:function(e){""!=e.error&&(sendFileChatErr=e.error,$("#sendFileFormChat").remove(),$("#sendFileLoader").remove(),alert("Error: "+e.error))},error:function(e){alert("An error occurred while sending the file!")}})})),1==sendFileCheck&&o[0]==i&&1==o[1]&&$("#submitFileChat").click(),l[0]==i&&1==l[1]&&1==sendFileCheck&&""!=sendFileChatErr)return $("#sendFileFormChat").remove(),$("#sendFileLoader").remove(),sendFileChatErr="",void(sendFileCheck=0);if("extension"==t.type||"group"==t.type){var r=t.ExtNo+"@"+wssServer;console.log("MESSAGE: "+r+" (extension)");var d=userAgent.message(r,n);d.data.direction="outbound",d.data.messageId=s,d.on("accepted",(function(i,n){var a;202==i.status_code?(console.log("Message Accepted:",s),null==(a=JSON.parse(localDB.getItem(e+"-stream")))&&null==a.DataCollection||($.each(a.DataCollection,(function(e,t){if("MSG"==t.ItemType&&t.ItemId==s)return t.Sent=!0,!1})),localDB.setItem(e+"-stream",JSON.stringify(a)),RefreshStream(t))):(console.warn("Message Error",i.status_code,n),null==(a=JSON.parse(localDB.getItem(e+"-stream")))&&null==a.DataCollection||($.each(a.DataCollection,(function(e,t){if("MSG"==t.ItemType&&t.ItemId==s)return t.Sent=!1,!1})),localDB.setItem(e+"-stream",JSON.stringify(a)),RefreshStream(t)))})),"undefined"!=typeof web_hook_on_message&&web_hook_on_message(d)}if(l[0]==i&&1==l[1]){var c=moment.utc().format("YYYY-MM-DD HH:mm:ss UTC"),u=JSON.parse(localDB.getItem(e+"-stream"));null==u&&(u=InitinaliseStream(e));var p={ItemId:s,ItemType:"MSG",ItemDate:c,SrcUserId:profileUserID,Src:'"'+profileName+'" <'+profileUser+">",DstUserId:e,Dst:"",MessageData:a};if(1==sendFileCheck){$("#sendFileFormChat").remove(),sendFileCheck=0;var g={ItemId:uID(),ItemType:"FILE",ItemDate:moment.utc().format("YYYY-MM-DD HH:mm:ss UTC"),SrcUserId:profileUserID,Src:'"'+profileName+'" <'+profileUser+">",DstUserId:e,Dst:t.ExtNo,SentFileName:upFileName,MessageData:"Download file"};""==sendFileChatErr&&u.DataCollection.push(g)}else $("#sendFileFormChat").remove();u.DataCollection.push(p),u.TotalRows=u.DataCollection.length,localDB.setItem(e+"-stream",JSON.stringify(u))}l[0]==i&&1==l[1]&&($("#sendFileLoader").remove(),$("#contact-"+e+"-ChatMessage").val("")),$("#contact-"+e+"-emoji-menu").hide(),null!=t.recognition&&(t.recognition.abort(),t.recognition=null),RefreshStream(t)}function ReceiveMessage(e){var t=e.remoteIdentity.displayName,i=e.remoteIdentity.uri.user;if(console.log("New Incoming Message!",'"'+t+'" <'+i+">"),e.data.direction="inbound",i.length>DidLength)console.warn("DID length greater then extensions length");else{var n=countSessions("0"),a=FindBuddyByDid(i);if(null==a){var o=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));null==o&&(o=InitUserBuddies());var l=uID(),s=utcDateNow();o.DataCollection.push({Type:"extension",LastActivity:s,ExtensionNumber:i,MobileNumber:"",ContactNumber1:"",ContactNumber2:"",uID:l,cID:null,gID:null,DisplayName:t,Position:"",Description:"",Email:"",MemberCount:0}),AddBuddy(a=new Buddy("extension",l,t,i,"","","",s,"",""),!0,0==n,!0),o.TotalRows=o.DataCollection.length,localDB.setItem(profileUserID+"-Buddies",JSON.stringify(o))}var r=e.body.split("|");if(""!=r[3]&&void 0!==r[3]&&null!=r[3])var d=1,c=r[3];else d=0,c="";var u=r[0],p=parseInt(r[1]),g=parseInt(r[2]);if(0!=g)if(g<p-1)splitMessage.hasOwnProperty(u)?splitMessage[u][g]=r[4]:splitMessage[u]={[g]:r[4]};else{if(g==p-1){if(splitMessage.hasOwnProperty(u)?splitMessage[u][g]=r[4]:splitMessage[u]={[g]:r[4]},Object.keys(splitMessage[u]).length!=p)return;var m=splitMessage[u].aeskeyandiv;delete splitMessage[u].aeskeyandiv;var f="",v=Object.keys(splitMessage[u]).sort().reduce((function(e,t){return e[t]=splitMessage[u][t],e}),{});Object.keys(v).forEach((function(e,t){f+=splitMessage[u][e]}));var h=decryptAES(f,m);delete splitMessage[u]}var b=uID(),y=utcDateNow();if("group"==a.type){var w=e.request.headers["P-Asserted-Identity"][0].raw.split(" <"),S=w[0];w[1].replace(">","");S}var _=JSON.parse(localDB.getItem(a.identity+"-stream"));null==_&&(_=InitinaliseStream(a.identity));var C={ItemId:b,ItemType:"MSG",ItemDate:y,SrcUserId:a.identity,Src:'"'+a.CallerIDName+'" <'+a.ExtNo+">",DstUserId:profileUserID,Dst:"",MessageData:h};if(1==d&&""!=c){d=0;var D={ItemId:uID(),ItemType:"FILE",ItemDate:moment.utc().format("YYYY-MM-DD HH:mm:ss UTC"),SrcUserId:a.identity,Src:'"'+a.CallerIDName+'" <'+a.ExtNo+">",DstUserId:profileUserID,Dst:profileUser,ReceivedFileName:c,MessageData:"Download file"};_.DataCollection.push(D)}if(_.DataCollection.push(C),_.TotalRows=_.DataCollection.length,localDB.setItem(a.identity+"-stream",JSON.stringify(_)),UpdateBuddyActivity(a.identity),RefreshStream(a),!$("#stream-"+a.identity).is(":visible")){if(IncreaseMissedBadge(a.identity),"Notification"in window&&"granted"===Notification.permission){var k=getPicture(a.identity),I={body:h.substring(0,250),icon:k};new Notification(lang.message_from+" : "+a.CallerIDName,I).onclick=function(e){SelectBuddy(a.identity)}}console.log("Audio:",audioBlobs.Alert.url);var x=new Audio(audioBlobs.Alert.blob);x.preload="auto",x.loop=!1,x.oncanplaythrough=function(e){void 0!==x.sinkId&&"default"!=getRingerOutputID()&&x.setSinkId(getRingerOutputID()).then((function(){console.log("Set sinkId to:",getRingerOutputID())})).catch((function(e){console.warn("Failed not apply setSinkId.",e)})),x.play().then((function(){})).catch((function(e){console.warn("Unable to play audio file.",e)}))},e.data.rinngerObj=x}}else if(splitMessage.hasOwnProperty(u))if(0==g){var T=r[4];(B=new JSEncrypt).setPrivateKey(currentChatPrivKey);var A=B.decrypt(T);splitMessage[u].aeskeyandiv=A}else splitMessage[u][g]=r[4];else if(0==g){var B;T=r[4];(B=new JSEncrypt).setPrivateKey(currentChatPrivKey);A=B.decrypt(T);splitMessage[u]={aeskeyandiv:A}}else splitMessage[u]={[g]:r[4]}}}function AddCallMessage(e,t,i,n){var a=JSON.parse(localDB.getItem(e+"-stream"));null==a&&(a=InitinaliseStream(e));var o=moment.utc(),l=0,s=0,r=0,d=moment.utc(t.data.callstart.replace(" UTC","")),c=null;t.startTime&&(c=moment.utc(t.startTime),l=moment.duration(o.diff(c)),r=moment.duration(c.diff(d))),s=moment.duration(o.diff(d)),console.log(t.data.reasonCode+"("+t.data.reasonText+")");var u="",p="",g="",m="";"inbound"==t.data.calldirection?(u=e,g=profileUserID,p="<"+t.remoteIdentity.uri.user+"> "+t.remoteIdentity.displayName,m="<"+profileUser+"> "+profileName):"outbound"==t.data.calldirection&&(u=profileUserID,g=e,p="<"+profileUser+"> "+profileName,m=t.remoteIdentity.uri.user);var f=t.data.calldirection,v=t.data.withvideo,h=t.id,b=t.data.terminateby,y={CdrId:uID(),ItemType:"CDR",ItemDate:d.format("YYYY-MM-DD HH:mm:ss UTC"),CallAnswer:c?c.format("YYYY-MM-DD HH:mm:ss UTC"):null,CallEnd:o.format("YYYY-MM-DD HH:mm:ss UTC"),SrcUserId:u,Src:p,DstUserId:g,Dst:m,RingTime:0!=r?r.asSeconds():0,Billsec:0!=l?l.asSeconds():0,TotalDuration:0!=s?s.asSeconds():0,ReasonCode:i,ReasonText:n,WithVideo:v,SessionId:h,CallDirection:f,Terminate:b,MessageData:null,Tags:[],Transfers:t.data.transfer?t.data.transfer:[],Mutes:t.data.mute?t.data.mute:[],Holds:t.data.hold?t.data.hold:[],Recordings:t.data.recordings?t.data.recordings:[],ConfCalls:t.data.confcalls?t.data.confcalls:[],QOS:[]};console.log("New CDR",y),a.DataCollection.push(y),a.TotalRows=a.DataCollection.length,localDB.setItem(e+"-stream",JSON.stringify(a)),UpdateBuddyActivity(e)}function SendImageDataMessage(e,t){if(null!=userAgent&&userAgent.isRegistered()){var i='<table class="ourChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr><td style="width: 80px"><div class=messageDate>'+moment.utc().format("YYYY-MM-DD HH:mm:ss UTC")+"</div></td><td><div class=ourChatMessageText>"+('<IMG class=previewImage onClick="PreviewImage(this)" src="'+t+'">')+"</div></td></tr></table>";$("#contact-"+e+"-ChatHistory").append(i),updateScroll(e),ImageEditor_Cancel(e),UpdateBuddyActivity(e)}}function SendFileDataMessage(e,t,i,n){if(null!=userAgent&&userAgent.isRegistered()){var a=uID();$.ajax({type:"POST",url:"/api/",data:"<XML>"+t+"</XML>",xhr:function(t){var i=$.ajaxSettings.xhr();return i.upload&&i.upload.addEventListener("progress",(function(t){var i=t.loaded/t.total*100;console.log("Progress for upload to "+e+" ("+a+"):"+i),$("#FileProgress-Bar-"+a).css("width",i+"%")}),!1),i},success:function(e,t,i){$("#FileUpload-"+a).html("Sent"),$("#FileProgress-"+a).hide(),$("#FileProgress-Bar-"+a).css("width","0%")},error:function(e,t,i){$("#FileUpload-"+a).html("Failed ("+e.status+")"),$("#FileProgress-"+a).hide(),$("#FileProgress-Bar-"+a).css("width","100%")}});var o=utcDateNow(),l=!1,s='<i class="fa fa-file"></i>';i.toLowerCase().endsWith(".png")&&(s='<i class="fa fa-file-image-o"></i>',l=!0),i.toLowerCase().endsWith(".jpg")&&(s='<i class="fa fa-file-image-o"></i>',l=!0),i.toLowerCase().endsWith(".jpeg")&&(s='<i class="fa fa-file-image-o"></i>',l=!0),i.toLowerCase().endsWith(".bmp")&&(s='<i class="fa fa-file-image-o"></i>',l=!0),i.toLowerCase().endsWith(".gif")&&(s='<i class="fa fa-file-image-o"></i>',l=!0),i.toLowerCase().endsWith(".mov")&&(s='<i class="fa fa-file-video-o"></i>'),i.toLowerCase().endsWith(".avi")&&(s='<i class="fa fa-file-video-o"></i>'),i.toLowerCase().endsWith(".mpeg")&&(s='<i class="fa fa-file-video-o"></i>'),i.toLowerCase().endsWith(".mp4")&&(s='<i class="fa fa-file-video-o"></i>'),i.toLowerCase().endsWith(".mvk")&&(s='<i class="fa fa-file-video-o"></i>'),i.toLowerCase().endsWith(".webm")&&(s='<i class="fa fa-file-video-o"></i>'),i.toLowerCase().endsWith(".wav")&&(s='<i class="fa fa-file-audio-o"></i>'),i.toLowerCase().endsWith(".mp3")&&(s='<i class="fa fa-file-audio-o"></i>'),i.toLowerCase().endsWith(".ogg")&&(s='<i class="fa fa-file-audio-o"></i>'),i.toLowerCase().endsWith(".zip")&&(s='<i class="fa fa-file-archive-o"></i>'),i.toLowerCase().endsWith(".rar")&&(s='<i class="fa fa-file-archive-o"></i>'),i.toLowerCase().endsWith(".tar.gz")&&(s='<i class="fa fa-file-archive-o"></i>'),i.toLowerCase().endsWith(".pdf")&&(s='<i class="fa fa-file-pdf-o"></i>');var r='<DIV><SPAN id="FileUpload-'+a+'">Sending</SPAN>: '+s+" "+i+"</DIV>";r+='<DIV id="FileProgress-'+a+'" class="progressBarContainer"><DIV id="FileProgress-Bar-'+a+'" class="progressBarTrack"></DIV></DIV>',l&&(r+='<DIV><IMG class=previewImage onClick="PreviewImage(this)" src="'+t+'"></DIV>');var d='<table class="ourChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr><td style="width: 80px"><div class=messageDate>'+o+"</div></td><td><div class=ourChatMessageText>"+r+"</div></td></tr></table>";$("#contact-"+e+"-ChatHistory").append(d),updateScroll(e),ImageEditor_Cancel(e),UpdateBuddyActivity(e)}}function updateLineScroll(e){RefreshLineActivity(e);var t=$("#line-"+e+"-CallDetails").get(0);t.scrollTop=t.scrollHeight}function updateScroll(e){var t=$("#contact-"+e+"-ChatHistory");t.children().length>0&&t.children().last().get(0).scrollIntoView(!1),t.get(0).scrollTop=t.get(0).scrollHeight}function PreviewImage(e){$.jeegoopopup.close();var t="<div>";t+='<div class="UiWindowField scroller">',t+='<div><img src="'+e.src+'"/></div>',t+="</div></div>",$.jeegoopopup.open({title:"Preview Image",html:t,width:"800",height:"600",center:!0,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}function IncreaseMissedBadge(e){var t=FindBuddyByIdentity(e);if(null!=t){t.missed+=1;var i=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));null!=i&&($.each(i.DataCollection,(function(t,i){if(i.uID==e||i.cID==e||i.gID==e)return i.missed=i.missed+1,!1})),localDB.setItem(profileUserID+"-Buddies",JSON.stringify(i))),$("#contact-"+e+"-missed").text(t.missed),$("#contact-"+e+"-missed").show(),console.log("Set Missed badge for "+e+" to: "+t.missed)}}function UpdateBuddyActivity(e){var t=FindBuddyByIdentity(e);if(null!=t){var i=utcDateNow();t.lastActivity=i,console.log("Last Activity is now: "+i);var n=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));null!=n&&($.each(n.DataCollection,(function(t,n){if(n.uID==e||n.cID==e||n.gID==e)return n.LastActivity=i,!1})),localDB.setItem(profileUserID+"-Buddies",JSON.stringify(n))),UpdateBuddyList()}}function ClearMissedBadge(e){var t=FindBuddyByIdentity(e);if(null!=t){t.missed=0;var i=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));null!=i&&($.each(i.DataCollection,(function(t,i){if(i.uID==e||i.cID==e||i.gID==e)return i.missed=0,!1})),localDB.setItem(profileUserID+"-Buddies",JSON.stringify(i))),$("#contact-"+e+"-missed").text(t.missed),$("#contact-"+e+"-missed").hide(400)}}function VideoCall(e,t){if(null!=userAgent&&userAgent.isRegistered()&&null!=e)if(0!=HasAudioDevice){if(0==HasVideoDevice)return console.warn("No video devices (webcam) found, switching to audio call."),void AudioCall(e,t);var i=navigator.mediaDevices.getSupportedConstraints(),n={sessionDescriptionHandlerOptions:{constraints:{audio:{deviceId:"default"},video:{deviceId:"default"}}}},a=getAudioSrcID();if("default"!=a){for(var o=!1,l=0;l<AudioinputDevices.length;++l)if(a==AudioinputDevices[l].deviceId){o=!0;break}o?n.sessionDescriptionHandlerOptions.constraints.audio.deviceId={exact:a}:(console.warn("The audio device you used before is no longer available, default settings applied."),localDB.setItem("AudioSrcId","default"))}i.autoGainControl&&(n.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl=AutoGainControl),i.echoCancellation&&(n.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation=EchoCancellation),i.noiseSuppression&&(n.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression=NoiseSuppression);var s=getVideoSrcID();if("default"!=s){var r=!1;for(l=0;l<VideoinputDevices.length;++l)if(s==VideoinputDevices[l].deviceId){r=!0;break}r?n.sessionDescriptionHandlerOptions.constraints.video.deviceId={exact:s}:(console.warn("The video device you used before is no longer available, default settings applied."),localDB.setItem("VideoSrcId","default"))}i.frameRate&&""!=maxFrameRate&&(n.sessionDescriptionHandlerOptions.constraints.video.frameRate=maxFrameRate),i.height&&""!=videoHeight&&(n.sessionDescriptionHandlerOptions.constraints.video.height=videoHeight),console.log(i),console.log(i.aspectRatio),console.log(videoAspectRatio),i.aspectRatio&&""!=videoAspectRatio&&(n.sessionDescriptionHandlerOptions.constraints.video.aspectRatio=videoAspectRatio),$("#line-"+e.LineNumber+"-msg").html(lang.starting_video_call),$("#line-"+e.LineNumber+"-timer").show(),console.log("INVITE (video): "+t+"@"+wssServer,n),e.SipSession=userAgent.invite("sip:"+t+"@"+wssServer,n);var d=moment.utc();e.SipSession.data.line=e.LineNumber,e.SipSession.data.buddyId=e.BuddyObj.identity,e.SipSession.data.calldirection="outbound",e.SipSession.data.dst=t,e.SipSession.data.callstart=d.format("YYYY-MM-DD HH:mm:ss UTC"),e.SipSession.data.callTimer=window.setInterval((function(){var t=moment.utc(),i=moment.duration(t.diff(d));$("#line-"+e.LineNumber+"-timer").html(formatShortDuration(i.asSeconds()))}),1e3),e.SipSession.data.VideoSourceDevice=getVideoSrcID(),e.SipSession.data.AudioSourceDevice=getAudioSrcID(),e.SipSession.data.AudioOutputDevice=getAudioOutputID(),e.SipSession.data.terminateby="them",e.SipSession.data.withvideo=!0,updateLineScroll(e.LineNumber),wireupVideoSession(e),"undefined"!=typeof web_hook_on_invite&&web_hook_on_invite(e.SipSession)}else Alert(lang.alert_no_microphone)}function ComposeEmail(e,t,i){i.stopPropagation(),SelectBuddy(e);var n=FindBuddyByIdentity(e);$("#roundcubeFrame").remove(),$("#rightContent").show(),$(".streamSelected").each((function(){$(this).css("display","none")})),$("#rightContent").append('<iframe id="roundcubeFrame" name="displayFrame"></iframe>');var a="",o="",l="",s="",r="";if($.ajax({async:!1,global:!1,type:"POST",url:"get-email-info.php",dataType:"JSON",data:{username:userName,s_ajax_call:validateSToken},success:function(e){a=e.rcdomain,o=encodeURIComponent(e.rcbasicauthuser),l=encodeURIComponent(e.rcbasicauthpass),s=e.rcuser,r=e.rcpassword},error:function(e){alert("An error occurred while trying to retrieve data from the database!")}}),""!=o&&""!=l)var d="https://"+o+":"+l+"@"+a+"/",c="https://"+o+":"+l+"@"+a+"/?_task=mail&_action=compose&_to="+encodeURIComponent(n.Email);else d="https://"+a+"/",c="https://"+a+"/?_task=mail&_action=compose&_to="+encodeURIComponent(n.Email);var u='<form id="rcForm" method="POST" action="'+d+'" target="displayFrame">';u+='<input type="hidden" name="_action" value="login" />',u+='<input type="hidden" name="_task" value="login" />',u+='<input type="hidden" name="_autologin" value="1" />',u+='<input name="_user" value="'+s+'" type="text" />',u+='<input name="_pass" value="'+r+'" type="password" />',u+='<input id="submitButton" type="submit" value="Login" />',u+="</form>",$("#roundcubeFrame").append(u),0==RCLoginCheck?($("#submitButton").click(),RCLoginCheck=1,""!=o&&""!=l?confirm('You are about to log in to the site "'+a+'" with the username "'+o+'".')&&$("#roundcubeFrame").attr("src",c):setTimeout((function(){$("#roundcubeFrame").attr("src",c)}),1e3)):$("#roundcubeFrame").attr("src",c)}function AudioCallMenu(e,t){if($(window).width()-event.pageX>54)var i=event.pageX-222;else i=event.pageX-276;if($(window).height()-event.pageY>140)var n=event.pageY+27;else n=event.pageY-80;var a=FindBuddyByIdentity(e);if("extension"==a.type){var o="<div id=quickCallMenu>";o+='<table id=quickCallTable cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">',o+='<tr class=quickNumDialRow><td><i class="fa fa-phone-square"></i></td><td>'+lang.call_extension+"</td><td><span class=quickNumToDial>"+a.ExtNo+"</span></td></tr>",null!=a.MobileNumber&&""!=a.MobileNumber&&(o+='<tr class=quickNumDialRow><td><i class="fa fa-mobile"></i></td><td>'+lang.call_mobile+"</td><td><span class=quickNumToDial>"+a.MobileNumber+"</span></td></tr>"),null!=a.ContactNumber1&&""!=a.ContactNumber1&&(o+='<tr class=quickNumDialRow><td><i class="fa fa-phone"></i></td><td>'+lang.call_number+"</td><td><span class=quickNumToDial>"+a.ContactNumber1+"</span></td></tr>"),null!=a.ContactNumber2&&""!=a.ContactNumber2&&(o+='<tr class=quickNumDialRow><td><i class="fa fa-phone"></i></td><td>'+lang.call_number+"</td><td><span class=quickNumToDial>"+a.ContactNumber2+"</span></td></tr>"),o+="</table>",o+="</div>";var l="Menu click AudioCall("+e+", "}else if("contact"==a.type){o="<div id=quickCallMenu>";o+='<table id=quickCallTable cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">',null!=a.MobileNumber&&""!=a.MobileNumber&&(o+='<tr class=quickNumDialRow><td><i class="fa fa-mobile"></i></td><td>'+lang.call_mobile+"</td><td><span class=quickNumToDial>"+a.MobileNumber+"</span></td></tr>"),null!=a.ContactNumber1&&""!=a.ContactNumber1&&(o+='<tr class=quickNumDialRow><td><i class="fa fa-phone"></i></td><td>'+lang.call_number+"</td><td><span class=quickNumToDial>"+a.ContactNumber1+"</span></td></tr>"),null!=a.ContactNumber2&&""!=a.ContactNumber2&&(o+='<tr class=quickNumDialRow><td><i class="fa fa-phone"></i></td><td>'+lang.call_number+"</td><td><span class=quickNumToDial>"+a.ContactNumber2+"</span></td></tr>"),o+="</table>",o+="</div>";l="Menu click AudioCall("+e+", "}else if("group"==a.type){o="<div id=quickCallMenu>";o+='<table id=quickCallTable cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">',o+='<tr class=quickNumDialRow><td><i class="fa fa-users"></i></td><td>'+lang.call_group+"</td><td><span class=quickNumToDial>"+a.ExtNo+"</span></td></tr>",o+="</table>",o+="</div>";l="Menu click AudioCallGroup("+e+", "}$.jeegoopopup.open({html:o,width:"auto",height:"auto",left:i,top:n,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!1,resizable:!1,fadeIn:0}),$("#quickCallTable").on("click",".quickNumDialRow",(function(){var t=$(this).closest("tr").find("span.quickNumToDial").html();console.log(l+t+")"),DialByLine("audio",e,t)})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}function AudioCall(e,t){if(null!=userAgent&&0!=userAgent.isRegistered()&&null!=e)if(0!=HasAudioDevice){var i=navigator.mediaDevices.getSupportedConstraints(),n={sessionDescriptionHandlerOptions:{constraints:{audio:{deviceId:"default"},video:!1}}},a=getAudioSrcID();if("default"!=a){for(var o=!1,l=0;l<AudioinputDevices.length;++l)if(a==AudioinputDevices[l].deviceId){o=!0;break}o?n.sessionDescriptionHandlerOptions.constraints.audio.deviceId={exact:a}:(console.warn("The audio device you used before is no longer available, default settings applied."),localDB.setItem("AudioSrcId","default"))}i.autoGainControl&&(n.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl=AutoGainControl),i.echoCancellation&&(n.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation=EchoCancellation),i.noiseSuppression&&(n.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression=NoiseSuppression),$("#line-"+e.LineNumber+"-msg").html(lang.starting_audio_call),$("#line-"+e.LineNumber+"-timer").show(),console.log("INVITE (audio): "+t+"@"+wssServer),e.SipSession=userAgent.invite("sip:"+t+"@"+wssServer,n);var s=moment.utc();e.SipSession.data.line=e.LineNumber,e.SipSession.data.buddyId=e.BuddyObj.identity,e.SipSession.data.calldirection="outbound",e.SipSession.data.dst=t,e.SipSession.data.callstart=s.format("YYYY-MM-DD HH:mm:ss UTC"),e.SipSession.data.callTimer=window.setInterval((function(){var t=moment.utc(),i=moment.duration(t.diff(s));$("#line-"+e.LineNumber+"-timer").html(formatShortDuration(i.asSeconds()))}),1e3),e.SipSession.data.VideoSourceDevice=null,e.SipSession.data.AudioSourceDevice=getAudioSrcID(),e.SipSession.data.AudioOutputDevice=getAudioOutputID(),e.SipSession.data.terminateby="them",e.SipSession.data.withvideo=!1,updateLineScroll(e.LineNumber),wireupAudioSession(e),"undefined"!=typeof web_hook_on_invite&&web_hook_on_invite(e.SipSession)}else Alert(lang.alert_no_microphone)}function getSession(e){if(null!=userAgent){if(0!=userAgent.isRegistered()){var t=null;return $.each(userAgent.sessions,(function(i,n){if(n.data.buddyId==e)return t=n,!1})),t}console.warn("userAgent is not registered")}else console.warn("userAgent is null")}function countSessions(e){var t=0;return null==userAgent?(console.warn("userAgent is null"),0):($.each(userAgent.sessions,(function(i,n){e!=n.id&&t++})),t)}function StartRecording(e){if("disabled"!=CallRecordingPolicy){var t=FindLineByNumber(e);if(null!=t){$("#line-"+t.LineNumber+"-btn-start-recording").hide(),$("#line-"+t.LineNumber+"-btn-stop-recording").show();var i=t.SipSession;if(null!=i){var n=uID();if(i.data.recordings||(i.data.recordings=[]),i.data.recordings.push({uID:n,startTime:utcDateNow(),stopTime:utcDateNow()}),i.data.mediaRecorder)"inactive"==i.data.mediaRecorder.state?(i.data.mediaRecorder.data={},i.data.mediaRecorder.data.id=""+n,i.data.mediaRecorder.data.sessionId=""+i.id,i.data.mediaRecorder.data.buddyId=""+t.BuddyObj.identity,console.log("Starting Call Recording",n),i.data.mediaRecorder.start(),i.data.recordings[i.data.recordings.length-1].startTime=utcDateNow(),$("#line-"+t.LineNumber+"-msg").html(lang.call_recording_started),updateLineScroll(e)):console.warn("Recorder is in an unknown state");else{console.log("Creating call recorder...");var a=new MediaStream,o=i.sessionDescriptionHandler.peerConnection;if(o.getSenders().forEach((function(e){e.track&&"audio"==e.track.kind&&(console.log("Adding sender audio track to record:",e.track.label),a.addTrack(e.track))})),o.getReceivers().forEach((function(e){e.track&&"audio"==e.track.kind&&(console.log("Adding receiver audio track to record:",e.track.label),a.addTrack(e.track)),i.data.withvideo&&e.track&&"video"==e.track.kind&&(console.log("Adding receiver video track to record:",e.track.label),a.addTrack(e.track))})),i.data.withvideo){var l=640,s=360,r=100;"HD"==RecordingVideoSize&&(l=1280,s=720,r=144),"FHD"==RecordingVideoSize&&(l=1920,s=1080,r=240);var d=$("#line-"+t.LineNumber+"-localVideo").get(0),c=$("#line-"+t.LineNumber+"-remoteVideo").get(0);"us-pnp"==RecordingLayout&&(d=$("#line-"+t.LineNumber+"-remoteVideo").get(0),c=$("#line-"+t.LineNumber+"-localVideo").get(0));var u=$("<canvas/>").get(0);u.width="side-by-side"==RecordingLayout?2*l+5:l,u.height=s;var p=u.getContext("2d");window.clearInterval(i.data.recordingRedrawInterval),i.data.recordingRedrawInterval=window.setInterval((function(){var e=c.videoWidth>0?c.videoWidth:l,t=c.videoHeight>0?c.videoHeight:s;if(e>=t){var i=l/e;if(e=l,(t*=i)>s){i=s/t;t=s,e*=i}}else{i=s/t;t=s,e*=i}var n=e<l?(l-e)/2:0,a=t<s?(s-t)/2:0;"side-by-side"==RecordingLayout&&(n=l+5+n);var o=d.videoHeight,g=d.videoWidth;if(o>0)if(g>=o){i=r/o;o=r,g*=i}else{i=r/g;g=r,o*=i}var m=10,f=10;if("side-by-side"==RecordingLayout){if((g=d.videoWidth)>=(o=d.videoHeight)){i=l/g;if(g=l,(o*=i)>s){i=s/o;o=s,g*=i}}else{i=s/o;o=s,g*=i}m=g<l?(l-g)/2:0,f=o<s?(s-o)/2:0}p.fillRect(0,0,u.width,u.height),c.videoHeight>0&&p.drawImage(c,n,a,e,t),d.videoHeight>0&&("side-by-side"==RecordingLayout||"us-pnp"==RecordingLayout||"them-pnp"==RecordingLayout)&&p.drawImage(d,m,f,g,o)}),Math.floor(1e3/RecordingVideoFps));var g=u.captureStream(RecordingVideoFps)}var m=new MediaStream;m.addTrack(MixAudioStreams(a).getAudioTracks()[0]),i.data.withvideo&&m.addTrack(g.getVideoTracks()[0]);var f="audio/webm";i.data.withvideo&&(f="video/webm");var v=new MediaRecorder(m,{mimeType:f});v.data={},v.data.id=""+n,v.data.sessionId=""+i.id,v.data.buddyId=""+t.BuddyObj.identity,v.ondataavailable=function(e){console.log("Got Call Recording Data: ",e.data.size+"Bytes",this.data.id,this.data.buddyId,this.data.sessionId),SaveCallRecording(e.data,this.data.id,this.data.buddyId,this.data.sessionId)},console.log("Starting Call Recording",n),i.data.mediaRecorder=v,i.data.mediaRecorder.start(),i.data.recordings[i.data.recordings.length-1].startTime=utcDateNow(),$("#line-"+t.LineNumber+"-msg").html(lang.call_recording_started),updateLineScroll(e)}}else console.warn("Could not find session")}}else console.warn("Policy Disabled: Call Recording")}function SaveCallRecording(e,t,i,n){var a=window.indexedDB.open("CallRecordings");a.onerror=function(e){console.error("IndexDB Request Error:",e)},a.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.");var t=e.target.result;if(0==t.objectStoreNames.contains("Recordings")){var i=t.createObjectStore("Recordings",{keyPath:"uID"});i.createIndex("sessionid","sessionid",{unique:!1}),i.createIndex("bytes","bytes",{unique:!1}),i.createIndex("type","type",{unique:!1}),i.createIndex("mediaBlob","mediaBlob",{unique:!1})}else console.warn("IndexDB requested upgrade, but object store was in place")},a.onsuccess=function(a){console.log("IndexDB connected to CallRecordings");var o=a.target.result;if(0!=o.objectStoreNames.contains("Recordings")){o.onerror=function(e){console.error("IndexDB Error:",e)};var l={uID:t,sessionid:n,bytes:e.size,type:e.type,mediaBlob:e};o.transaction(["Recordings"],"readwrite").objectStore("Recordings").add(l).onsuccess=function(a){console.log("Call Recording Sucess: ",t,e.size,e.type,i,n)}}else console.warn("IndexDB CallRecordings.Recordings does not exists")}}function StopRecording(e,t){var i=FindLineByNumber(e);if(null!=i&&null!=i.SipSession){var n=i.SipSession;if(1==t)return $("#line-"+i.LineNumber+"-btn-start-recording").show(),$("#line-"+i.LineNumber+"-btn-stop-recording").hide(),void(n.data.mediaRecorder&&("recording"==n.data.mediaRecorder.state?(console.log("Stopping Call Recording"),n.data.mediaRecorder.stop(),n.data.recordings[n.data.recordings.length-1].stopTime=utcDateNow(),window.clearInterval(n.data.recordingRedrawInterval),$("#line-"+i.LineNumber+"-msg").html(lang.call_recording_stopped),updateLineScroll(e)):console.warn("Recorder is in an unknow state")));"enabled"==CallRecordingPolicy&&console.log("Policy Enabled: Call Recording"),Confirm(lang.confirm_stop_recording,lang.stop_recording,(function(){$("#line-"+i.LineNumber+"-btn-start-recording").show(),$("#line-"+i.LineNumber+"-btn-stop-recording").hide(),n.data.mediaRecorder&&("recording"==n.data.mediaRecorder.state?(console.log("Stopping Call Recording"),n.data.mediaRecorder.stop(),n.data.recordings[n.data.recordings.length-1].stopTime=utcDateNow(),window.clearInterval(n.data.recordingRedrawInterval),$("#line-"+i.LineNumber+"-msg").html(lang.call_recording_stopped),updateLineScroll(e)):console.warn("Recorder is in an unknow state"))}))}}function PlayAudioCallRecording(e,t,i){var n=$(e).parent();n.empty();var a=new Audio;a.autoplay=!1,a.controls=!0;var o=getAudioOutputID();void 0!==a.sinkId?a.setSinkId(o).then((function(){console.log("sinkId applied: "+o)})).catch((function(e){console.warn("Error using setSinkId: ",e)})):console.warn("setSinkId() is not possible using this browser."),n.append(a);var l=window.indexedDB.open("CallRecordings");l.onerror=function(e){console.error("IndexDB Request Error:",e)},l.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.")},l.onsuccess=function(e){console.log("IndexDB connected to CallRecordings");var n=e.target.result;if(0!=n.objectStoreNames.contains("Recordings")){var o=n.transaction(["Recordings"]).objectStore("Recordings").get(i);o.onerror=function(e){console.error("IndexDB Get Error:",e)},o.onsuccess=function(e){$("#cdr-media-meta-size-"+t+"-"+i).html(" Size: "+formatBytes(e.target.result.bytes)),$("#cdr-media-meta-codec-"+t+"-"+i).html(" Codec: "+e.target.result.type),a.src=window.URL.createObjectURL(e.target.result.mediaBlob),a.oncanplaythrough=function(){a.play().then((function(){console.log("Playback started")})).catch((function(e){console.error("Error playing back file: ",e)}))}}}else console.warn("IndexDB CallRecordings.Recordings does not exists")}}function PlayVideoCallRecording(e,t,i,n){var a=$(e).parent();a.empty();var o=$("<video>").get(0);o.id="callrecording-video-"+t,o.autoplay=!1,o.controls=!0,o.ontimeupdate=function(e){$("#cdr-video-meta-width-"+t+"-"+i).html(lang.width+" : "+e.target.videoWidth+"px"),$("#cdr-video-meta-height-"+t+"-"+i).html(lang.height+" : "+e.target.videoHeight+"px")};var l=getAudioOutputID();void 0!==o.sinkId?o.setSinkId(l).then((function(){console.log("sinkId applied: "+l)})).catch((function(e){console.warn("Error using setSinkId: ",e)})):console.warn("setSinkId() is not possible using this browser."),a.append(o);var s=window.indexedDB.open("CallRecordings");s.onerror=function(e){console.error("IndexDB Request Error:",e)},s.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.")},s.onsuccess=function(e){console.log("IndexDB connected to CallRecordings");var a=e.target.result;if(0!=a.objectStoreNames.contains("Recordings")){var l=a.transaction(["Recordings"]).objectStore("Recordings").get(i);l.onerror=function(e){console.error("IndexDB Get Error:",e)},l.onsuccess=function(e){$("#cdr-media-meta-size-"+t+"-"+i).html(" Size: "+formatBytes(e.target.result.bytes)),$("#cdr-media-meta-codec-"+t+"-"+i).html(" Codec: "+e.target.result.type),o.src=window.URL.createObjectURL(e.target.result.mediaBlob),o.oncanplaythrough=function(){try{o.scrollIntoViewIfNeeded(!1)}catch(e){}o.play().then((function(){console.log("Playback started")})).catch((function(e){console.error("Error playing back file: ",e)})),n&&window.setTimeout((function(){var e=$("<canvas>").get(0),a=o.videoWidth,l=o.videoHeight;if(a>l){if(l>225){var s=225/l;l=225,a*=s}}else if(l>225){s=225/a;a=225,l*=s}e.width=a,e.height=l,e.getContext("2d").drawImage(o,0,0,a,l),e.toBlob((function(e){var o=new FileReader;o.readAsDataURL(e),o.onloadend=function(){var e={width:a,height:l,posterBase64:o.result};console.log("Capturing Video Poster...");var s=JSON.parse(localDB.getItem(n+"-stream"));null==s&&null==s.DataCollection||($.each(s.DataCollection,(function(n,a){if("CDR"==a.ItemType&&a.CdrId==t)return a.Recordings&&a.Recordings.length>=1&&$.each(a.Recordings,(function(t,n){n.uID==i&&(n.Poster=e)})),!1})),localDB.setItem(n+"-stream",JSON.stringify(s)),console.log("Capturing Video Poster, Done"))}}),"image/jpeg",PosterJpegQuality)}),1e3)}}}else console.warn("IndexDB CallRecordings.Recordings does not exists")}}function MixAudioStreams(e){var t=null;try{window.AudioContext=window.AudioContext||window.webkitAudioContext,t=new AudioContext}catch(t){return console.warn("AudioContext() not available, cannot record"),e}var i=t.createMediaStreamDestination();return e.getAudioTracks().forEach((function(e){var n=new MediaStream;n.addTrack(e),t.createMediaStreamSource(n).connect(i)})),i.stream}function QuickFindBuddy(e){$.jeegoopopup.close();var t=e.offsetWidth+178,i=e.offsetHeight+68;$(window).width()<1467&&(i=e.offsetHeight+164,$(window).width()<918&&(t=e.offsetWidth-140,$(window).width()<690&&(t=e.offsetWidth-70,i=e.offsetHeight+164)));var n=e.value;if(""!=n){console.log("Find Buddy: ",n),Buddies.sort((function(e,t){return e.CallerIDName<t.CallerIDName?-1:e.CallerIDName>t.CallerIDName?1:0}));var a=0,o='<div id="quickSearchBuddy">';o+='<table id="quickSearchBdTable" cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">';for(var l=0;l<Buddies.length;l++){var s=Buddies[l],r=!1;if(s.CallerIDName.toLowerCase().indexOf(n.toLowerCase())>-1&&(r=!0),s.ExtNo.toLowerCase().indexOf(n.toLowerCase())>-1&&(r=!0),s.Desc.toLowerCase().indexOf(n.toLowerCase())>-1&&(r=!0),s.MobileNumber.toLowerCase().indexOf(n.toLowerCase())>-1&&(r=!0),s.ContactNumber1.toLowerCase().indexOf(n.toLowerCase())>-1&&(r=!0),s.ContactNumber2.toLowerCase().indexOf(n.toLowerCase())>-1&&(r=!0),r){var d="#404040";"Unknown"!=s.presence&&"Not online"!=s.presence&&"Unavailable"!=s.presence||(d="#666666"),"Ready"==s.presence&&(d="#3fbd3f"),"On the phone"!=s.presence&&"Ringing"!=s.presence&&"On hold"!=s.presence||(d="#c99606"),o+='<tr class="quickFindBdTagRow"><td></td><td><b>'+s.CallerIDName+"</b></td><td></td></tr>",""!=s.ExtNo&&(o+='<tr class="quickFindBdRow"><td><i class="fa fa-phone-square" style="color:'+d+'"></i></td><td>'+lang.extension+" ("+s.presence+')</td><td><span class="quickNumFound">'+s.ExtNo+"</span></td></tr>"),""!=s.MobileNumber&&(o+='<tr class="quickFindBdRow"><td><i class="fa fa-mobile"></i></td><td>'+lang.mobile+'</td><td><span class="quickNumFound">'+s.MobileNumber+"</span></td></tr>"),""!=s.ContactNumber1&&(o+='<tr class="quickFindBdRow"><td><i class="fa fa-phone"></i></td><td>'+lang.contact_number_1+'</td><td><span class="quickNumFound">'+s.ContactNumber1+"</span></td></tr>"),""!=s.ContactNumber2&&(o+='<tr class="quickFindBdRow"><td><i class="fa fa-phone"></i></td><td>'+lang.contact_number_2+'</td><td><span class="quickNumFound">'+s.ContactNumber2+"</span></td></tr>"),a++}if(a>=5)break}(o+="</table></div>").length>1&&($.jeegoopopup.open({html:o,width:"auto",height:"auto",left:t,top:i,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!1,resizable:!1,fadeIn:0}),$("#jg_popup_inner").focus(),$("#jg_popup_inner #jg_popup_content #quickSearchBuddy #quickSearchBdTable").on("click",".quickFindBdRow",(function(){var e=$(this).closest("tr").find("span.quickNumFound").html();$.jeegoopopup.close(),$(document).find("input[id*='-txt-FindTransferBuddy']").focus(),$(document).find("input[id*='-txt-FindTransferBuddy']").val(e)})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()})))}}function StartTransferSession(e){$("#line-"+e+"-btn-Transfer").hide(),$("#line-"+e+"-btn-CancelTransfer").show(),holdSession(e),$("#line-"+e+"-txt-FindTransferBuddy").val(""),$("#line-"+e+"-txt-FindTransferBuddy").parent().show(),$("#line-"+e+"-btn-blind-transfer").show(),$("#line-"+e+"-btn-attended-transfer").show(),$("#line-"+e+"-btn-complete-transfer").hide(),$("#line-"+e+"-btn-cancel-transfer").hide(),$("#line-"+e+"-transfer-status").hide(),$("#line-"+e+"-Transfer").show(),updateLineScroll(e)}function CancelTransferSession(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;if(i.data.childsession){console.log("Child Transfer call detected:",i.data.childsession.status);try{i.data.childsession.status==SIP.Session.C.STATUS_CONFIRMED?i.data.childsession.bye():i.data.childsession.cancel()}catch(e){}}$("#line-"+e+"-btn-Transfer").show(),$("#line-"+e+"-btn-CancelTransfer").hide(),unholdSession(e),$("#line-"+e+"-Transfer").hide(),updateLineScroll(e)}else console.warn("Null line or session")}function BlindTransfer(e){var t=$("#line-"+e+"-txt-FindTransferBuddy").val().replace(/[^0-9\*\#\+]/g,"");if(""!=t){var i=FindLineByNumber(e);if(null!=i&&null!=i.SipSession){var n=i.SipSession;n.data.transfer||(n.data.transfer=[]),n.data.transfer.push({type:"Blind",to:t,transferTime:utcDateNow(),disposition:"refer",dispositionTime:utcDateNow(),accept:{complete:null,eventTime:null,disposition:""}});var a=n.data.transfer.length-1,o={receiveResponse:function(t){console.log("Blind transfer response: ",t.reason_phrase),n.data.terminateby="refer",n.data.transfer[a].accept.disposition=t.reason_phrase,n.data.transfer[a].accept.eventTime=utcDateNow(),$("#line-"+e+"-msg").html("Call Blind Transfered (Accepted)"),updateLineScroll(e)}};console.log("REFER: ",t+"@"+wssServer),n.refer("sip:"+t+"@"+wssServer,o),$("#line-"+e+"-msg").html(lang.call_blind_transfered),updateLineScroll(e)}else console.warn("Null line or session")}else console.warn("Cannot transfer, must be [0-9*+#]")}function AttendedTransfer(e){var t=$("#line-"+e+"-txt-FindTransferBuddy").val().replace(/[^0-9\*\#\+]/g,"");if(""!=t){var i=FindLineByNumber(e);if(null!=i&&null!=i.SipSession){var n=i.SipSession;$.jeegoopopup.close(),$("#line-"+e+"-txt-FindTransferBuddy").parent().hide(),$("#line-"+e+"-btn-blind-transfer").hide(),$("#line-"+e+"-btn-attended-transfer").hide(),$("#line-"+e+"-btn-complete-attended-transfer").hide(),$("#line-"+e+"-btn-cancel-attended-transfer").hide(),$("#line-"+e+"-btn-terminate-attended-transfer").hide();var a=$("#line-"+e+"-transfer-status");a.html(lang.connecting),a.show(),n.data.transfer||(n.data.transfer=[]),n.data.transfer.push({type:"Attended",to:t,transferTime:utcDateNow(),disposition:"invite",dispositionTime:utcDateNow(),accept:{complete:null,eventTime:null,disposition:""}});var o=n.data.transfer.length-1;updateLineScroll(e);var l=navigator.mediaDevices.getSupportedConstraints(),s={sessionDescriptionHandlerOptions:{constraints:{audio:{deviceId:"default"},video:!1}}};"default"!=n.data.AudioSourceDevice&&(s.sessionDescriptionHandlerOptions.constraints.audio.deviceId={exact:n.data.AudioSourceDevice}),l.autoGainControl&&(s.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl=AutoGainControl),l.echoCancellation&&(s.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation=EchoCancellation),l.noiseSuppression&&(s.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression=NoiseSuppression),n.data.withvideo&&(s.sessionDescriptionHandlerOptions.constraints.video=!0,"default"!=n.data.VideoSourceDevice&&(s.sessionDescriptionHandlerOptions.constraints.video.deviceId={exact:n.data.VideoSourceDevice}),l.frameRate&&""!=maxFrameRate&&(s.sessionDescriptionHandlerOptions.constraints.video.frameRate=maxFrameRate),l.height&&""!=videoHeight&&(s.sessionDescriptionHandlerOptions.constraints.video.height=videoHeight),l.aspectRatio&&""!=videoAspectRatio&&(s.sessionDescriptionHandlerOptions.constraints.video.aspectRatio=videoAspectRatio)),console.log("INVITE: ","sip:"+t+"@"+wssServer);var r=userAgent.invite("sip:"+t+"@"+wssServer,s);n.data.childsession=r,r.on("progress",(function(t){a.html(lang.ringing),n.data.transfer[o].disposition="progress",n.data.transfer[o].dispositionTime=utcDateNow(),$("#line-"+e+"-msg").html(lang.attended_transfer_call_started);var i=$("#line-"+e+"-btn-cancel-attended-transfer");i.off("click"),i.on("click",(function(){r.cancel(),a.html(lang.call_cancelled),console.log("New call session canceled"),n.data.transfer[o].accept.complete=!1,n.data.transfer[o].accept.disposition="cancel",n.data.transfer[o].accept.eventTime=utcDateNow(),$("#line-"+e+"-msg").html(lang.attended_transfer_call_cancelled),updateLineScroll(e)})),i.show(),updateLineScroll(e)})),r.on("accepted",(function(t){a.html(lang.call_in_progress),$("#line-"+e+"-btn-cancel-attended-transfer").hide(),n.data.transfer[o].disposition="accepted",n.data.transfer[o].dispositionTime=utcDateNow();var i=$("#line-"+e+"-btn-complete-attended-transfer");i.off("click"),i.on("click",(function(){var t={receiveResponse:function(t){console.log("Attended transfer response: ",t.reason_phrase),n.data.terminateby="refer",n.data.transfer[o].accept.disposition=t.reason_phrase,n.data.transfer[o].accept.eventTime=utcDateNow(),$("#line-"+e+"-msg").html(lang.attended_transfer_complete_accepted),updateLineScroll(e)}};n.refer(r,t),a.html(lang.attended_transfer_complete),console.log("Attended transfer complete"),n.data.transfer[o].accept.complete=!0,n.data.transfer[o].accept.disposition="refer",n.data.transfer[o].accept.eventTime=utcDateNow(),$("#line-"+e+"-msg").html(lang.attended_transfer_complete),updateLineScroll(e)})),i.show(),updateLineScroll(e);var l=$("#line-"+e+"-btn-terminate-attended-transfer");l.off("click"),l.on("click",(function(){r.bye(),a.html(lang.call_ended),console.log("New call session end"),n.data.transfer[o].accept.complete=!1,n.data.transfer[o].accept.disposition="bye",n.data.transfer[o].accept.eventTime=utcDateNow(),$("#line-"+e+"-msg").html(lang.attended_transfer_call_ended),updateLineScroll(e)})),l.show(),updateLineScroll(e)})),r.on("trackAdded",(function(){var t=r.sessionDescriptionHandler.peerConnection,i=new MediaStream;t.getReceivers().forEach((function(e){e.track&&"audio"==e.track.kind&&i.addTrack(e.track)}));var a=$("#line-"+e+"-transfer-remoteAudio").get(0);a.srcObject=i,a.onloadedmetadata=function(e){void 0!==a.sinkId&&a.setSinkId(n.data.AudioOutputDevice).then((function(){console.log("sinkId applied: "+n.data.AudioOutputDevice)})).catch((function(e){console.warn("Error using setSinkId: ",e)})),a.play()}})),r.on("rejected",(function(t,i){console.log("New call session rejected: ",i),a.html(lang.call_rejected),n.data.transfer[o].disposition="rejected",n.data.transfer[o].dispositionTime=utcDateNow(),$("#line-"+e+"-txt-FindTransferBuddy").parent().show(),$("#line-"+e+"-btn-blind-transfer").show(),$("#line-"+e+"-btn-attended-transfer").show(),$("#line-"+e+"-btn-complete-attended-transfer").hide(),$("#line-"+e+"-btn-cancel-attended-transfer").hide(),$("#line-"+e+"-btn-terminate-attended-transfer").hide(),$("#line-"+e+"-msg").html(lang.attended_transfer_call_rejected),updateLineScroll(e),window.setTimeout((function(){a.hide(),updateLineScroll(e)}),1e3)})),r.on("terminated",(function(t,i){console.log("New call session terminated: ",i),a.html(lang.call_ended),n.data.transfer[o].disposition="terminated",n.data.transfer[o].dispositionTime=utcDateNow(),$("#line-"+e+"-txt-FindTransferBuddy").parent().show(),$("#line-"+e+"-btn-blind-transfer").show(),$("#line-"+e+"-btn-attended-transfer").show(),$("#line-"+e+"-btn-complete-attended-transfer").hide(),$("#line-"+e+"-btn-cancel-attended-transfer").hide(),$("#line-"+e+"-btn-terminate-attended-transfer").hide(),$("#line-"+e+"-msg").html(lang.attended_transfer_call_terminated),updateLineScroll(e),window.setTimeout((function(){a.hide(),updateLineScroll(e)}),1e3)}))}else console.warn("Null line or session")}else console.warn("Cannot transfer, must be [0-9*+#]")}function StartConferenceCall(e){$("#line-"+e+"-btn-Conference").hide(),$("#line-"+e+"-btn-CancelConference").show(),holdSession(e),$("#line-"+e+"-txt-FindConferenceBuddy").val(""),$("#line-"+e+"-txt-FindConferenceBuddy").parent().show(),$("#line-"+e+"-btn-conference-dial").show(),$("#line-"+e+"-btn-cancel-conference-dial").hide(),$("#line-"+e+"-btn-join-conference-call").hide(),$("#line-"+e+"-btn-terminate-conference-call").hide(),$("#line-"+e+"-conference-status").hide(),$("#line-"+e+"-Conference").show(),updateLineScroll(e)}function CancelConference(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;if(i.data.childsession)try{i.data.childsession.status==SIP.Session.C.STATUS_CONFIRMED?i.data.childsession.bye():i.data.childsession.cancel()}catch(e){}$("#line-"+e+"-btn-Conference").show(),$("#line-"+e+"-btn-CancelConference").hide(),unholdSession(e),$("#line-"+e+"-Conference").hide(),updateLineScroll(e)}else console.warn("Null line or session")}function ConferenceDial(t){var i=$("#line-"+t+"-txt-FindConferenceBuddy").val().replace(/[^0-9\*\#\+]/g,"");if(""!=i){var n=FindLineByNumber(t);if(null!=n&&null!=n.SipSession){var a=n.SipSession;$.jeegoopopup.close(),$("#line-"+t+"-txt-FindConferenceBuddy").parent().hide(),$("#line-"+t+"-btn-conference-dial").hide(),$("#line-"+t+"-btn-cancel-conference-dial"),$("#line-"+t+"-btn-join-conference-call").hide(),$("#line-"+t+"-btn-terminate-conference-call").hide();var o=$("#line-"+t+"-conference-status");o.html(lang.connecting),o.show(),a.data.confcalls||(a.data.confcalls=[]),a.data.confcalls.push({to:i,startTime:utcDateNow(),disposition:"invite",dispositionTime:utcDateNow(),accept:{complete:null,eventTime:null,disposition:""}});var l=a.data.confcalls.length-1;updateLineScroll(t);var s=navigator.mediaDevices.getSupportedConstraints(),r={sessionDescriptionHandlerOptions:{constraints:{audio:{deviceId:"default"},video:!1}}};"default"!=a.data.AudioSourceDevice&&(r.sessionDescriptionHandlerOptions.constraints.audio.deviceId={exact:a.data.AudioSourceDevice}),s.autoGainControl&&(r.sessionDescriptionHandlerOptions.constraints.audio.autoGainControl=AutoGainControl),s.echoCancellation&&(r.sessionDescriptionHandlerOptions.constraints.audio.echoCancellation=EchoCancellation),s.noiseSuppression&&(r.sessionDescriptionHandlerOptions.constraints.audio.noiseSuppression=NoiseSuppression),a.data.withvideo&&(r.sessionDescriptionHandlerOptions.constraints.video=!0,"default"!=a.data.VideoSourceDevice&&(r.sessionDescriptionHandlerOptions.constraints.video.deviceId={exact:a.data.VideoSourceDevice}),s.frameRate&&""!=maxFrameRate&&(r.sessionDescriptionHandlerOptions.constraints.video.frameRate=maxFrameRate),s.height&&""!=videoHeight&&(r.sessionDescriptionHandlerOptions.constraints.video.height=videoHeight),s.aspectRatio&&""!=videoAspectRatio&&(r.sessionDescriptionHandlerOptions.constraints.video.aspectRatio=videoAspectRatio)),console.log("INVITE: ","sip:"+i+"@"+wssServer);var d=userAgent.invite("sip:"+i+"@"+wssServer,r);a.data.childsession=d,d.on("progress",(function(e){o.html(lang.ringing),a.data.confcalls[l].disposition="progress",a.data.confcalls[l].dispositionTime=utcDateNow(),$("#line-"+t+"-msg").html(lang.conference_call_started);var i=$("#line-"+t+"-btn-cancel-conference-dial");i.off("click"),i.on("click",(function(){d.cancel(),o.html(lang.call_cancelled),console.log("New call session canceled"),a.data.confcalls[l].accept.complete=!1,a.data.confcalls[l].accept.disposition="cancel",a.data.confcalls[l].accept.eventTime=utcDateNow(),$("#line-"+t+"-msg").html(lang.canference_call_cancelled),updateLineScroll(t)})),i.show(),updateLineScroll(t)})),d.on("accepted",(function(e){o.html(lang.call_in_progress),$("#line-"+t+"-btn-cancel-conference-dial").hide(),a.data.confcalls[l].complete=!0,a.data.confcalls[l].disposition="accepted",a.data.confcalls[l].dispositionTime=utcDateNow();var i=$("#line-"+t+"-btn-join-conference-call");i.off("click"),i.on("click",(function(){if(a.data.childsession){var e=new MediaStream,n=new MediaStream,s=a.sessionDescriptionHandler.peerConnection,r=a.data.childsession.sessionDescriptionHandler.peerConnection;r.getReceivers().forEach((function(t){t.track&&"audio"==t.track.kind&&(console.log("Adding conference session:",t.track.label),e.addTrack(t.track))})),s.getReceivers().forEach((function(e){e.track&&"audio"==e.track.kind&&(console.log("Adding conference session:",e.track.label),n.addTrack(e.track))})),s.getSenders().forEach((function(t){if(t.track&&"audio"==t.track.kind){console.log("Switching to mixed Audio track on session"),a.data.AudioSourceTrack=t.track,e.addTrack(t.track);var i=MixAudioStreams(e).getAudioTracks()[0];i.IsMixedTrack=!0,t.replaceTrack(i)}})),r.getSenders().forEach((function(e){if(e.track&&"audio"==e.track.kind){console.log("Switching to mixed Audio track on conf call"),a.data.childsession.data.AudioSourceTrack=e.track,n.addTrack(e.track);var t=MixAudioStreams(n).getAudioTracks()[0];t.IsMixedTrack=!0,e.replaceTrack(t)}})),o.html(lang.call_in_progress),console.log("Conference Call In Progress"),a.data.confcalls[l].accept.complete=!0,a.data.confcalls[l].accept.disposition="join",a.data.confcalls[l].accept.eventTime=utcDateNow(),$("#line-"+t+"-btn-terminate-conference-call").show(),$("#line-"+t+"-msg").html(lang.conference_call_in_progress),unholdSession(t),i.hide(),updateLineScroll(t)}else console.warn("Conference session lost")})),i.show(),updateLineScroll(t);var n=$("#line-"+t+"-btn-terminate-conference-call");n.off("click"),n.on("click",(function(){d.bye(),o.html(lang.call_ended),console.log("New call session end"),a.data.confcalls[l].accept.disposition="bye",a.data.confcalls[l].accept.eventTime=utcDateNow(),$("#line-"+t+"-msg").html(lang.conference_call_ended),updateLineScroll(t)})),n.show(),updateLineScroll(t)})),d.on("trackAdded",(function(){var e=d.sessionDescriptionHandler.peerConnection,i=new MediaStream;e.getReceivers().forEach((function(e){e.track&&"audio"==e.track.kind&&i.addTrack(e.track)}));var n=$("#line-"+t+"-conference-remoteAudio").get(0);n.srcObject=i,n.onloadedmetadata=function(e){void 0!==n.sinkId&&n.setSinkId(a.data.AudioOutputDevice).then((function(){console.log("sinkId applied: "+a.data.AudioOutputDevice)})).catch((function(e){console.warn("Error using setSinkId: ",e)})),n.play()}})),d.on("rejected",(function(e,i){console.log("New call session rejected: ",i),o.html(lang.call_rejected),a.data.confcalls[l].disposition="rejected",a.data.confcalls[l].dispositionTime=utcDateNow(),$("#line-"+t+"-txt-FindConferenceBuddy").parent().show(),$("#line-"+t+"-btn-conference-dial").show(),$("#line-"+t+"-btn-cancel-conference-dial").hide(),$("#line-"+t+"-btn-join-conference-call").hide(),$("#line-"+t+"-btn-terminate-conference-call").hide(),$("#line-"+t+"-msg").html(lang.conference_call_rejected),updateLineScroll(t),window.setTimeout((function(){o.hide(),updateLineScroll(t)}),1e3)})),d.on("terminated",(function(i,n){(console.log("New call session terminated: ",n),o.html(lang.call_ended),a.data.confcalls[l].disposition="terminated",a.data.confcalls[l].dispositionTime=utcDateNow(),a.data.childsession.data.AudioSourceTrack&&"audio"==a.data.childsession.data.AudioSourceTrack.kind&&a.data.childsession.data.AudioSourceTrack.stop(),a.data.AudioSourceTrack&&"audio"==a.data.AudioSourceTrack.kind)&&a.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(t){t.track&&"audio"==t.track.kind&&(t.replaceTrack(a.data.AudioSourceTrack).then((function(){a.data.ismute&&(t.track.enabled=!1)})).catch((function(){console.error(e)})),a.data.AudioSourceTrack=null)}));$("#line-"+t+"-txt-FindConferenceBuddy").parent().show(),$("#line-"+t+"-btn-conference-dial").show(),$("#line-"+t+"-btn-cancel-conference-dial").hide(),$("#line-"+t+"-btn-join-conference-call").hide(),$("#line-"+t+"-btn-terminate-conference-call").hide(),$("#line-"+t+"-msg").html(lang.conference_call_terminated),updateLineScroll(t),window.setTimeout((function(){o.hide(),updateLineScroll(t)}),1e3)}))}else console.warn("Null line or session")}else console.warn("Cannot transfer, must be [0-9*+#]")}function cancelSession(e){var t=FindLineByNumber(e);null!=t&&null!=t.SipSession&&(t.SipSession.data.terminateby="us",console.log("Cancelling session : "+e),t.SipSession.cancel(),$("#line-"+e+"-msg").html(lang.call_cancelled))}function holdSession(e){var t=FindLineByNumber(e);null!=t&&null!=t.SipSession&&(console.log("Putting Call on hold: "+e),0==t.SipSession.local_hold&&t.SipSession.hold(),t.SipSession.data.hold||(t.SipSession.data.hold=[]),t.SipSession.data.hold.push({event:"hold",eventTime:utcDateNow()}),$("#line-"+e+"-btn-Hold").hide(),$("#line-"+e+"-btn-Unhold").show(),$("#line-"+e+"-msg").html(lang.call_on_hold),updateLineScroll(e))}function unholdSession(e){var t=FindLineByNumber(e);null!=t&&null!=t.SipSession&&(console.log("Taking call off hold: "+e),1==t.SipSession.local_hold&&t.SipSession.unhold(),t.SipSession.data.hold||(t.SipSession.data.hold=[]),t.SipSession.data.hold.push({event:"unhold",eventTime:utcDateNow()}),$("#line-"+e+"-msg").html(lang.call_in_progress),$("#line-"+e+"-btn-Hold").show(),$("#line-"+e+"-btn-Unhold").hide(),updateLineScroll(e))}function endSession(e){var t=FindLineByNumber(e);null!=t&&null!=t.SipSession&&(console.log("Ending call with: "+e),t.SipSession.data.terminateby="us",t.SipSession.bye(),$("#line-"+e+"-msg").html(lang.call_ended),$("#line-"+e+"-ActiveCall").hide(),updateLineScroll(e))}function sendDTMF(e,t){var i=FindLineByNumber(e);null!=i&&null!=i.SipSession&&(console.log("Sending DTMF ("+t+"): "+e),i.SipSession.dtmf(t),$("#line-"+e+"-msg").html(lang.send_dtmf+": "+t),updateLineScroll(e),"undefined"!=typeof web_hook_on_dtmf&&web_hook_on_dtmf(t,i.SipSession))}function switchVideoSource(t,i){var n=FindLineByNumber(t);if(null!=n&&null!=n.SipSession){var a=n.SipSession;$("#line-"+t+"-msg").html(lang.switching_video_source);var o=navigator.mediaDevices.getSupportedConstraints(),l={audio:!1,video:{deviceId:"default"}};"default"!=i&&(l.video.deviceId={exact:i}),o.frameRate&&""!=maxFrameRate&&(l.video.frameRate=maxFrameRate),o.height&&""!=videoHeight&&(l.video.height=videoHeight),o.aspectRatio&&""!=videoAspectRatio&&(l.video.aspectRatio=videoAspectRatio),a.data.VideoSourceDevice=i;var s=a.sessionDescriptionHandler.peerConnection,r=new MediaStream;navigator.mediaDevices.getUserMedia(l).then((function(e){var t=e.getVideoTracks()[0];s.getSenders().forEach((function(e){e.track&&"video"==e.track.kind&&(console.log("Switching Video Track : "+e.track.label+" to "+t.label),e.track.stop(),e.replaceTrack(t),r.addTrack(t))}))})).catch((function(e){console.error("Error on getUserMedia",e,l)})),a.data.AudioSourceTrack&&"audio"==a.data.AudioSourceTrack.kind&&s.getSenders().forEach((function(t){t.track&&"audio"==t.track.kind&&(t.replaceTrack(a.data.AudioSourceTrack).then((function(){a.data.ismute&&(t.track.enabled=!1)})).catch((function(){console.error(e)})),a.data.AudioSourceTrack=null)})),console.log("Showing as preview...");var d=$("#line-"+t+"-localVideo").get(0);d.srcObject=r,d.onloadedmetadata=function(e){d.play()}}else console.warn("Line or Session is Null")}function SendCanvas(t){var i=FindLineByNumber(t);if(null!=i&&null!=i.SipSession){var n=i.SipSession;$("#line-"+t+"-msg").html(lang.switching_to_canvas),RemoveScratchpad(t);var a=$("<canvas/>");a.prop("id","line-"+t+"-scratchpad"),$("#line-"+t+"-scratchpad-container").append(a),$("#line-"+t+"-scratchpad").css("display","inline-block"),$("#line-"+t+"-scratchpad").css("width","640px"),$("#line-"+t+"-scratchpad").css("height","360px"),$("#line-"+t+"-scratchpad").prop("width",640),$("#line-"+t+"-scratchpad").prop("height",360),$("#line-"+t+"-scratchpad-container").show(),console.log("Canvas for Scratchpad created..."),scratchpad=new fabric.Canvas("line-"+t+"-scratchpad"),scratchpad.id="line-"+t+"-scratchpad",scratchpad.backgroundColor="#FFFFFF",scratchpad.isDrawingMode=!0,scratchpad.renderAll(),scratchpad.redrawIntrtval=window.setInterval((function(){scratchpad.renderAll()}),1e3),CanvasCollection.push(scratchpad);var o=$("#line-"+t+"-scratchpad").get(0).captureStream(25),l=o.getVideoTracks()[0],s=n.sessionDescriptionHandler.peerConnection;s.getSenders().forEach((function(e){e.track&&"video"==e.track.kind&&(console.log("Switching Track : "+e.track.label+" to Scratchpad Canvas"),e.track.stop(),e.replaceTrack(l))})),n.data.AudioSourceTrack&&"audio"==n.data.AudioSourceTrack.kind&&s.getSenders().forEach((function(t){t.track&&"audio"==t.track.kind&&(t.replaceTrack(n.data.AudioSourceTrack).then((function(){n.data.ismute&&(t.track.enabled=!1)})).catch((function(){console.error(e)})),n.data.AudioSourceTrack=null)})),console.log("Showing as preview...");var r=$("#line-"+t+"-localVideo").get(0);r.srcObject=o,r.onloadedmetadata=function(e){r.play()}}else console.warn("Line or Session is Null")}function SendVideo(e,t){var i=FindLineByNumber(e);if(null!=i&&null!=i.SipSession){var n=i.SipSession;$("#line-"+e+"-src-camera").prop("disabled",!1),$("#line-"+e+"-src-canvas").prop("disabled",!1),$("#line-"+e+"-src-desktop").prop("disabled",!1),$("#line-"+e+"-src-video").prop("disabled",!0),$("#line-"+e+"-src-blank").prop("disabled",!1),$("#line-"+e+"-msg").html(lang.switching_to_shared_video),$("#line-"+e+"-scratchpad-container").hide(),RemoveScratchpad(e),$("#line-"+e+"-sharevideo").hide(),$("#line-"+e+"-sharevideo").get(0).pause(),$("#line-"+e+"-sharevideo").get(0).removeAttribute("src"),$("#line-"+e+"-sharevideo").get(0).load(),$("#line-"+e+"-localVideo").hide(),$("#line-"+e+"-remoteVideo").appendTo("#line-"+e+"-preview-container");var a=$("#line-"+e+"-sharevideo");a.prop("src",t),a.off("loadedmetadata"),a.on("loadedmetadata",(function(){console.log("Video can play now... ");var t=360;"HD"==VideoResampleSize&&(t=720),"FHD"==VideoResampleSize&&(t=1080);var i=a.get(0),o=$("<canvas/>").get(0),l=i.videoWidth,s=i.videoHeight;if(l>=s){if(s>t){var r=t/s;s=t,l*=r}}else if(l>t){r=t/l;l=t,s*=r}o.width=l,o.height=s;var d=o.getContext("2d");window.clearInterval(n.data.videoResampleInterval),n.data.videoResampleInterval=window.setInterval((function(){d.drawImage(i,0,0,l,s)}),40);var c=null;"captureStream"in i?c=i.captureStream():"mozCaptureStream"in i?c=i.mozCaptureStream():console.warn("Cannot capture stream from video, this will result in no audio being transmitted.");var u=o.captureStream(25).getVideoTracks()[0],p=null!=c?c.getAudioTracks()[0]:null;n.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(e){if(e.track&&"video"==e.track.kind&&(console.log("Switching Track : "+e.track.label),e.track.stop(),e.replaceTrack(u)),e.track&&"audio"==e.track.kind){console.log("Switching to mixed Audio track on session"),n.data.AudioSourceTrack=e.track;var t=new MediaStream;p&&t.addTrack(p),t.addTrack(e.track);var i=MixAudioStreams(t).getAudioTracks()[0];i.IsMixedTrack=!0,e.replaceTrack(i)}})),console.log("Showing as preview...");var g=$("#line-"+e+"-localVideo").get(0);g.srcObject=c,g.onloadedmetadata=function(e){g.play().then((function(){console.log("Playing Preview Video File")})).catch((function(e){console.error("Cannot play back video",e)}))},console.log("Starting Video..."),$("#line-"+e+"-sharevideo").get(0).play()})),$("#line-"+e+"-sharevideo").show(),console.log("Video for Sharing created...")}else console.warn("Line or Session is Null")}function ShareScreen(t){var i=FindLineByNumber(t);if(null!=i&&null!=i.SipSession){var n=i.SipSession;$("#line-"+t+"-msg").html(lang.switching_to_shared_screeen);var a=new MediaStream,o=n.sessionDescriptionHandler.peerConnection;if(navigator.getDisplayMedia){var l={video:!0,audio:!1};navigator.getDisplayMedia(l).then((function(e){console.log("navigator.getDisplayMedia");var i=e.getVideoTracks()[0];o.getSenders().forEach((function(e){e.track&&"video"==e.track.kind&&(console.log("Switching Video Track : "+e.track.label+" to Screen"),e.track.stop(),e.replaceTrack(i),a.addTrack(i))})),console.log("Showing as preview...");var n=$("#line-"+t+"-localVideo").get(0);n.srcObject=a,n.onloadedmetadata=function(e){n.play()}})).catch((function(e){console.error("Error on getUserMedia")}))}else if(navigator.mediaDevices.getDisplayMedia){l={video:!0,audio:!1};navigator.mediaDevices.getDisplayMedia(l).then((function(e){console.log("navigator.mediaDevices.getDisplayMedia");var i=e.getVideoTracks()[0];o.getSenders().forEach((function(e){e.track&&"video"==e.track.kind&&(console.log("Switching Video Track : "+e.track.label+" to Screen"),e.track.stop(),e.replaceTrack(i),a.addTrack(i))})),console.log("Showing as preview...");var n=$("#line-"+t+"-localVideo").get(0);n.srcObject=a,n.onloadedmetadata=function(e){n.play()}})).catch((function(e){console.error("Error on getUserMedia")}))}else{l={video:{mediaSource:"screen"},audio:!1};navigator.mediaDevices.getUserMedia(l).then((function(e){console.log("navigator.mediaDevices.getUserMedia");var i=e.getVideoTracks()[0];o.getSenders().forEach((function(e){e.track&&"video"==e.track.kind&&(console.log("Switching Video Track : "+e.track.label+" to Screen"),e.track.stop(),e.replaceTrack(i),a.addTrack(i))})),console.log("Showing as preview...");var n=$("#line-"+t+"-localVideo").get(0);n.srcObject=a,n.onloadedmetadata=function(e){n.play()}})).catch((function(e){console.error("Error on getUserMedia")}))}n.data.AudioSourceTrack&&"audio"==n.data.AudioSourceTrack.kind&&o.getSenders().forEach((function(t){t.track&&"audio"==t.track.kind&&(t.replaceTrack(n.data.AudioSourceTrack).then((function(){n.data.ismute&&(t.track.enabled=!1)})).catch((function(){console.error(e)})),n.data.AudioSourceTrack=null)}))}else console.warn("Line or Session is Null")}function DisableVideoStream(t){var i=FindLineByNumber(t);if(null!=i&&null!=i.SipSession){var n=i.SipSession;n.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(t){t.track&&"video"==t.track.kind&&(console.log("Disable Video Track : "+t.track.label),t.track.enabled=!1),t.track&&"audio"==t.track.kind&&n.data.AudioSourceTrack&&"audio"==n.data.AudioSourceTrack.kind&&(t.replaceTrack(n.data.AudioSourceTrack).then((function(){n.data.ismute&&(t.track.enabled=!1)})).catch((function(){console.error(e)})),n.data.AudioSourceTrack=null)})),console.log("Showing as preview...");var a=$("#line-"+t+"-localVideo").get(0);a.pause(),a.removeAttribute("src"),a.load(),$("#line-"+t+"-msg").html(lang.video_disabled)}else console.warn("Line or Session is Null")}var Line=function(e,t,i,n){this.LineNumber=e,this.DisplayName=t,this.DisplayNumber=i,this.IsSelected=!1,this.BuddyObj=n,this.SipSession=null,this.LocalSoundMeter=null,this.RemoteSoundMeter=null};function ShowDial(e){var t=e.offsetWidth+104,i=0,n=e.offsetHeight+117;$(window).width()<=915&&(t=event.pageX+e.offsetWidth-120,i=0,n=event.pageY+e.offsetHeight-11);var a='<div id=mainDialPad><div><input id=dialText class=dialTextInput oninput="handleDialInput(this, event)" onkeydown="dialOnkeydown(event, this)"></div>';a+='<table cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">',a+="<tr><td><button class=dtmfButtons onclick=\"KeyPress('1');new Audio('sounds/dtmf.mp3').play();\"><div>1</div><span> </span></button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('2');new Audio('sounds/dtmf.mp3').play();\"><div>2</div><span>ABC</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('3');new Audio('sounds/dtmf.mp3').play();\"><div>3</div><span>DEF</span></button></td></tr>",a+="<tr><td><button class=dtmfButtons onclick=\"KeyPress('4');new Audio('sounds/dtmf.mp3').play();\"><div>4</div><span>GHI</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('5');new Audio('sounds/dtmf.mp3').play();\"><div>5</div><span>JKL</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('6');new Audio('sounds/dtmf.mp3').play();\"><div>6</div><span>MNO</span></button></td></tr>",a+="<tr><td><button class=dtmfButtons onclick=\"KeyPress('7');new Audio('sounds/dtmf.mp3').play();\"><div>7</div><span>PQRS</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('8');new Audio('sounds/dtmf.mp3').play();\"><div>8</div><span>TUV</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('9');new Audio('sounds/dtmf.mp3').play();\"><div>9</div><span>WXYZ</span></button></td></tr>",a+="<tr><td><button class=dtmfButtons onclick=\"KeyPress('*');new Audio('sounds/dtmf.mp3').play();\">*</button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('0');new Audio('sounds/dtmf.mp3').play();\">0</button></td>",a+="<td><button class=dtmfButtons onclick=\"KeyPress('#');new Audio('sounds/dtmf.mp3').play();\">#</button></td></tr>",a+="</table>",a+='<div style="text-align: center;">',a+='<button class="roundButtons dialButtons" id=dialAudio style="width:48px; height:48px;" title="'+lang.audio_call+'" onclick="DialByLine(\'audio\')"><i class="fa fa-phone"></i></button>',EnableVideoCalling&&(a+='<button class="roundButtons dialButtons" id=dialVideo style="width:48px; height:48px; margin-left:20px" title="'+lang.video_call+'" onclick="DialByLine(\'video\')"><i class="fa fa-video-camera"></i></button>'),a+="</div></div>",$.jeegoopopup.open({html:a,width:"auto",height:"auto",left:t,right:i,top:n,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!0,resizable:!1,fadeIn:0}),$("#dialText").focus(),$(window).width()<=915?$.jeegoopopup.right(6):$.jeegoopopup.width("auto").height("auto").left(t).top(n),$("#jg_popup_overlay").click((function(){$("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close())}))}function handleDialInput(e,t){EnableAlphanumericDial?$("#dialText").val($("#dialText").val().replace(/[^\da-zA-Z\*\#\+]/g,"").substring(0,MaxDidLength)):$("#dialText").val($("#dialText").val().replace(/[^\d\*\#\+]/g,"").substring(0,MaxDidLength)),$("#dialVideo").prop("disabled",$("#dialText").val().length>=DidLength)}function dialOnkeydown(e,t,i){if("13"==(e.keyCode?e.keyCode:e.which))return e.preventDefault(),DialByLine("audio"),$("#jg_popup_b").empty(),$("#jg_popup_l").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close(),!1}function KeyPress(e){$("#dialText").val(($("#dialText").val()+e).substring(0,MaxDidLength)),$("#dialVideo").prop("disabled",$("#dialText").val().length>=DidLength)}function DialByLine(e,t,i,n){if($.jeegoopopup.close(),null!=userAgent&&0!=userAgent.isRegistered()){var a=i||$("#dialText").val();if(0!=(a=EnableAlphanumericDial?a.replace(/[^\da-zA-Z\*\#\+]/g,"").substring(0,MaxDidLength):a.replace(/[^\d\*\#\+]/g,"").substring(0,MaxDidLength)).length){var o=t?FindBuddyByIdentity(t):FindBuddyByDid(a);if(null==o){var l=a.length>DidLength?"contact":"extension";"*"!=l.substring(0,1)&&"#"!=l.substring(0,1)||(l="contact"),o=MakeBuddy(l,!0,!1,!0,n||a,a)}newLineNumber+=1,lineObj=new Line(newLineNumber,o.CallerIDName,a,o),Lines.push(lineObj),AddLineHtml(lineObj),SelectLine(newLineNumber),UpdateBuddyList(),"audio"==e?AudioCall(lineObj,a):VideoCall(lineObj,a);try{$("#line-"+newLineNumber).get(0).scrollIntoViewIfNeeded()}catch(e){}}else console.warn("Enter number to dial")}else ConfigureExtensionWindow()}function SelectLine(e){$("#roundcubeFrame").remove();var t=FindLineByNumber(e);if(null!=t){for(var i=0,n=0;n<Lines.length;n++)if(Lines[n].LineNumber==t.LineNumber&&(i=n+1),1==Lines[n].IsSelected&&Lines[n].LineNumber==t.LineNumber)return;console.log("Selecting Line : "+t.LineNumber),$(".streamSelected").each((function(){$(this).prop("class","stream")})),$("#line-ui-"+t.LineNumber).prop("class","streamSelected"),$("#line-ui-"+t.LineNumber+"-DisplayLineNo").html('<i class="fa fa-phone"></i> '+lang.line+" "+i),$("#line-ui-"+t.LineNumber+"-LineIcon").html(i),SwitchLines(t.LineNumber);for(n=0;n<Lines.length;n++){var a=Lines[n].LineNumber==t.LineNumber?"buddySelected":"buddy";null!=Lines[n].SipSession&&(a=Lines[n].SipSession.local_hold?"buddyActiveCallHollding":"buddyActiveCall"),$("#line-"+Lines[n].LineNumber).prop("class",a),Lines[n].IsSelected=Lines[n].LineNumber==t.LineNumber}for(var o=0;o<Buddies.length;o++)$("#contact-"+Buddies[o].identity).prop("class","buddy"),Buddies[o].IsSelected=!1;UpdateUI()}}function FindLineByNumber(e){for(var t=0;t<Lines.length;t++)if(Lines[t].LineNumber==e)return Lines[t];return null}function AddLineHtml(e){var t='<table id="line-ui-'+e.LineNumber+'" class="stream" cellspacing="5" cellpadding="0">';t+="<tr><td class=streamSection>",t+='<div style="float:left; margin:0px; padding:5px; height:38px; line-height:38px">',t+='<button id="line-'+e.LineNumber+'-btn-back" onclick="CloseLine(\''+e.LineNumber+'\')" class=roundButtons title="'+lang.back+'"><i class="fa fa-chevron-left"></i></button> ',t+="</div>",t+='<div class=contact style="float: left;">',t+='<div id="line-ui-'+e.LineNumber+'-LineIcon" class=lineIcon>'+e.LineNumber+"</div>",t+='<div id="line-ui-'+e.LineNumber+'-DisplayLineNo" class=contactNameText><i class="fa fa-phone"></i> '+lang.line+" "+e.LineNumber+"</div>",t+="<div class=presenceText>"+e.DisplayName+" <"+e.DisplayNumber+"></div>",t+="</div>",t+='<div style="float:right; line-height: 46px;">',t+="</div>",t+='<div style="clear:both; height:0px"></div>',t+='<div id="line-'+e.LineNumber+'-calling">',t+='<div id="line-'+e.LineNumber+'-timer" style="float: right; margin-top: 4px; margin-right: 10px; color: #575757; display:none;"></div>',t+='<div id="line-'+e.LineNumber+'-msg" class=callStatus style="display:none">...</div>',t+='<div id="line-'+e.LineNumber+'-progress" style="display:none; margin-top: 10px">',t+="<div class=progressCall>",t+="<button onclick=\"cancelSession('"+e.LineNumber+'\')" class=hangupButton><i class="fa fa-phone"></i> '+lang.cancel+"</button>",t+="</div>",t+="</div>",t+='<div id="line-'+e.LineNumber+'-ActiveCall" style="display:none; margin-top: 10px;">',t+='<div id="line-'+e.LineNumber+'-conference" style="display:none;"></div>',"extension"==e.BuddyObj.type&&(t+='<div id="line-'+e.LineNumber+'-VideoCall" class=videoCall style="display:none;">',t+='<div style="height:35px; line-height:35px; text-align: right">'+lang.present+": ",t+='<div class=pill-nav style="border-color:#333333">',t+='<button id="line-'+e.LineNumber+'-src-camera" onclick="PresentCamera(\''+e.LineNumber+'\')" title="'+lang.camera+'" disabled><i class="fa fa-video-camera"></i></button>',t+='<button id="line-'+e.LineNumber+'-src-canvas" onclick="PresentScratchpad(\''+e.LineNumber+'\')" title="'+lang.scratchpad+'"><i class="fa fa-pencil-square"></i></button>',t+='<button id="line-'+e.LineNumber+'-src-desktop" onclick="PresentScreen(\''+e.LineNumber+'\')" title="'+lang.screen+'"><i class="fa fa-desktop"></i></button>',t+='<button id="line-'+e.LineNumber+'-src-video" onclick="PresentVideo(\''+e.LineNumber+'\')" title="'+lang.video+'"><i class="fa fa-file-video-o"></i></button>',t+='<button id="line-'+e.LineNumber+'-src-blank" onclick="PresentBlank(\''+e.LineNumber+'\')" title="'+lang.blank+'"><i class="fa fa-ban"></i></button>',t+="</div>",t+=' <button id="line-'+e.LineNumber+'-expand" onclick="ExpandVideoArea(\''+e.LineNumber+'\')"><i class="fa fa-expand"></i></button>',t+='<button id="line-'+e.LineNumber+'-restore" onclick="RestoreVideoArea(\''+e.LineNumber+'\')" style="display:none"><i class="fa fa-compress"></i></button>',t+="</div>",t+='<div id="line-'+e.LineNumber+'-preview-container" class=PreviewContainer>',t+='<video id="line-'+e.LineNumber+'-localVideo" muted></video>',t+="</div>",t+='<div id="line-'+e.LineNumber+'-stage-container" class=StageContainer>',t+='<video id="line-'+e.LineNumber+'-remoteVideo" muted></video>',t+='<div id="line-'+e.LineNumber+'-scratchpad-container" style="display:none"></div>',t+='<video id="line-'+e.LineNumber+'-sharevideo" controls muted style="display:none; object-fit: contain;"></video>',t+="</div>",t+="</div>"),t+='<div id="line-'+e.LineNumber+'-AudioCall" style="display:none;">',t+='<audio id="line-'+e.LineNumber+'-remoteAudio"></audio>',t+="</div>",t+='<div style="text-align:center">',t+='<div style="margin-top:10px">',t+='<button id="line-'+e.LineNumber+'-btn-ShowDtmf" onclick="ShowDtmfMenu(this, \''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.show_key_pad+'"><i class="fa fa-keyboard-o"></i></button>',t+='<button id="line-'+e.LineNumber+'-btn-Mute" onclick="MuteSession(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.mute+'"><i class="fa fa-microphone-slash"></i></button>',t+='<button id="line-'+e.LineNumber+'-btn-Unmute" onclick="UnmuteSession(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.unmute+'" style="color: red; display:none"><i class="fa fa-microphone"></i></button>',"undefined"==typeof MediaRecorder||"allow"!=CallRecordingPolicy&&"enabled"!=CallRecordingPolicy||(t+='<button id="line-'+e.LineNumber+'-btn-start-recording" onclick="StartRecording(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.start_call_recording+'"><i class="fa fa-dot-circle-o"></i></button>',t+='<button id="line-'+e.LineNumber+'-btn-stop-recording" onclick="StopRecording(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.stop_call_recording+'" style="color: red; display:none"><i class="fa fa-circle"></i></button>'),EnableTransfer&&(t+='<button id="line-'+e.LineNumber+'-btn-Transfer" onclick="StartTransferSession(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.transfer_call+'"><i class="fa fa-reply" style="transform: rotateY(180deg)"></i></button>',t+='<button id="line-'+e.LineNumber+'-btn-CancelTransfer" onclick="CancelTransferSession(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.cancel_transfer+'" style="color: red; display:none"><i class="fa fa-reply" style="transform: rotateY(180deg)"></i></button>'),t+='<button id="line-'+e.LineNumber+'-btn-Hold" onclick="holdSession(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.hold_call+'"><i class="fa fa-pause-circle"></i></button>',t+='<button id="line-'+e.LineNumber+'-btn-Unhold" onclick="unholdSession(\''+e.LineNumber+'\')" class="roundButtons inCallButtons" title="'+lang.resume_call+'" style="color: red; display:none"><i class="fa fa-play-circle"></i></button>',t+='<button id="line-'+e.LineNumber+'-btn-End" onclick="endSession(\''+e.LineNumber+'\')" class="roundButtons inCallButtons hangupButton" title="'+lang.end_call+'"><i class="fa fa-phone"></i></button>',t+="</div>",t+='<div id="line-'+e.LineNumber+'-Transfer" style="display:none">',t+='<div style="margin-top:10px">',t+='<span class=searchClean><input id="line-'+e.LineNumber+'-txt-FindTransferBuddy" oninput="QuickFindBuddy(this,\''+e.LineNumber+'\')" type=text autocomplete=none style="width:150px;" autocomplete=none placeholder="'+lang.search_or_enter_number+'"></span>',t+=' <button id="line-'+e.LineNumber+'-btn-blind-transfer" onclick="BlindTransfer(\''+e.LineNumber+'\')"><i class="fa fa-reply" style="transform: rotateY(180deg)"></i> '+lang.blind_transfer+"</button>",t+=' <button id="line-'+e.LineNumber+'-btn-attended-transfer" onclick="AttendedTransfer(\''+e.LineNumber+'\')"><i class="fa fa-reply-all" style="transform: rotateY(180deg)"></i> '+lang.attended_transfer+"</button>",t+=' <button id="line-'+e.LineNumber+'-btn-complete-attended-transfer" style="display:none"><i class="fa fa-reply-all" style="transform: rotateY(180deg)"></i> '+lang.complete_transfer+"</buuton>",t+=' <button id="line-'+e.LineNumber+'-btn-cancel-attended-transfer" style="display:none"><i class="fa fa-phone" style="transform: rotate(135deg);"></i> '+lang.cancel_transfer+"</buuton>",t+=' <button id="line-'+e.LineNumber+'-btn-terminate-attended-transfer" style="display:none"><i class="fa fa-phone" style="transform: rotate(135deg);"></i> '+lang.end_transfer_call+"</buuton>",t+="</div>",t+='<div id="line-'+e.LineNumber+'-transfer-status" class=callStatus style="margin-top:10px; display:none">...</div>',t+='<audio id="line-'+e.LineNumber+'-transfer-remoteAudio" style="display:none"></audio>',t+="</div>",t+='<div id="line-'+e.LineNumber+'-Conference" style="display:none">',t+='<div style="margin-top:10px">',t+='<span class=searchClean><input id="line-'+e.LineNumber+'-txt-FindConferenceBuddy" oninput="QuickFindBuddy(this,\''+e.LineNumber+'\')" type=text autocomplete=none style="width:150px;" autocomplete=none placeholder="'+lang.search_or_enter_number+'"></span>',t+=' <button id="line-'+e.LineNumber+'-btn-conference-dial" onclick="ConferenceDial(\''+e.LineNumber+'\')"><i class="fa fa-phone"></i> '+lang.call+"</button>",t+=' <button id="line-'+e.LineNumber+'-btn-cancel-conference-dial" style="display:none"><i class="fa fa-phone"></i> '+lang.cancel_call+"</buuton>",t+=' <button id="line-'+e.LineNumber+'-btn-join-conference-call" style="display:none"><i class="fa fa-users"></i> '+lang.join_conference_call+"</buuton>",t+=' <button id="line-'+e.LineNumber+'-btn-terminate-conference-call" style="display:none"><i class="fa fa-phone"></i> '+lang.end_conference_call+"</buuton>",t+="</div>",t+='<div id="line-'+e.LineNumber+'-conference-status" class=callStatus style="margin-top:10px; display:none">...</div>',t+='<audio id="line-'+e.LineNumber+'-conference-remoteAudio" style="display:none"></audio>',t+="</div>",t+='<div id="line-'+e.LineNumber+'-monitoring" style="margin-top:10px;margin-bottom:10px;">',t+='<span style="vertical-align: middle"><i class="fa fa-microphone"></i></span> ',t+='<span class=meterContainer title="'+lang.microphone_levels+'">',t+='<span id="line-'+e.LineNumber+'-Mic" class=meterLevel style="height:0%"></span>',t+="</span> ",t+='<span style="vertical-align: middle"><i class="fa fa-volume-up"></i></span> ',t+='<span class=meterContainer title="'+lang.speaker_levels+'">',t+='<span id="line-'+e.LineNumber+'-Speaker" class=meterLevel style="height:0%"></span>',t+="</span> ",t+='<button id="line-'+e.LineNumber+'-btn-settings" onclick="ChangeSettings(\''+e.LineNumber+'\', this)"><i class="fa fa-cogs"></i> '+lang.device_settings+"</button>",t+='<button id="line-'+e.LineNumber+'-call-stats" onclick="ShowCallStats(\''+e.LineNumber+'\', this)"><i class="fa fa-area-chart"></i> '+lang.call_stats+"</button>",t+="</div>",t+='<div id="line-'+e.LineNumber+'-AudioStats" class="audioStats cleanScroller" style="display:none">',t+='<div style="text-align:right"><button onclick="HideCallStats(\''+e.LineNumber+'\', this)"><i class="fa fa-times" style="font-size:20px;"></i></button></div>',t+="<fieldset class=audioStatsSet onclick=\"HideCallStats('"+e.LineNumber+"', this)\">",t+="<legend>"+lang.send_statistics+"</legend>",t+='<canvas id="line-'+e.LineNumber+'-AudioSendBitRate" class=audioGraph width=600 height=160 style="width:600px; height:160px"></canvas>',t+='<canvas id="line-'+e.LineNumber+'-AudioSendPacketRate" class=audioGraph width=600 height=160 style="width:600px; height:160px"></canvas>',t+="</fieldset>",t+="<fieldset class=audioStatsSet onclick=\"HideCallStats('"+e.LineNumber+"', this)\">",t+="<legend>"+lang.receive_statistics+"</legend>",t+='<canvas id="line-'+e.LineNumber+'-AudioReceiveBitRate" class=audioGraph width=600 height=160 style="width:600px; height:160px"></canvas>',t+='<canvas id="line-'+e.LineNumber+'-AudioReceivePacketRate" class=audioGraph width=600 height=160 style="width:600px; height:160px"></canvas>',t+='<canvas id="line-'+e.LineNumber+'-AudioReceivePacketLoss" class=audioGraph width=600 height=160 style="width:600px; height:160px"></canvas>',t+='<canvas id="line-'+e.LineNumber+'-AudioReceiveJitter" class=audioGraph width=600 height=160 style="width:600px; height:160px"></canvas>',t+='<canvas id="line-'+e.LineNumber+'-AudioReceiveLevels" class=audioGraph width=600 height=160 style="width:600px; height:160px"></canvas>',t+="</fieldset>",t+="</div>",t+="</div>",t+="</div>",t+="</div>",t+="</td></tr>",t+='<tr><td class="streamSection streamSectionBackground">',t+='<div id="line-'+e.LineNumber+'-CallDetails" class="chatHistory cleanScroller">',t+="</div>",t+="</td></tr>",t+="</table>",$("#rightContent").append(t)}function RemoveLine(e){if(null!=e){for(var t=0;t<Lines.length;t++)if(Lines[t].LineNumber==e.LineNumber){Lines.splice(t,1);break}CloseLine(e.LineNumber),$("#line-ui-"+e.LineNumber).remove(),UpdateBuddyList(),null!=localDB.getItem("SelectedBuddy")&&(console.log("Selecting previously selected buddy...",localDB.getItem("SelectedBuddy")),SelectBuddy(localDB.getItem("SelectedBuddy")),UpdateUI())}}function CloseLine(e){$(".buddySelected").each((function(){$(this).prop("class","buddy")})),$(".streamSelected").each((function(){$(this).prop("class","stream")})),SwitchLines(0),console.log("Closing Line: "+e);for(var t=0;t<Lines.length;t++)Lines[t].IsSelected=!1;selectedLine=null;for(var i=0;i<Buddies.length;i++)Buddies[i].IsSelected=!1;selectedBuddy=null,$.jeegoopopup.close(),UpdateUI()}function SwitchLines(e){$.each(userAgent.sessions,(function(t,i){0==i.local_hold&&i.data.line!=e&&(console.log("Putting an active call on hold: Line: "+i.data.line+" buddy: "+i.data.buddyId),i.hold(),i.data.hold||(i.data.hold=[]),i.data.hold.push({event:"hold",eventTime:utcDateNow()})),$("#line-"+i.data.line+"-btn-Hold").hide(),$("#line-"+i.data.line+"-btn-Unhold").show(),i.data.IsCurrentCall=!1}));var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;1==i.local_hold&&(console.log("Taking call off hold: Line: "+e+" buddy: "+i.data.buddyId),i.unhold(),i.data.hold||(i.data.hold=[]),i.data.hold.push({event:"unhold",eventTime:utcDateNow()})),$("#line-"+e+"-btn-Hold").show(),$("#line-"+e+"-btn-Unhold").hide(),i.data.IsCurrentCall=!0}selectedLine=e,RefreshLineActivity(e)}function RefreshLineActivity(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;$("#line-"+e+"-CallDetails").empty();var n=[],a=0,o=moment.utc(i.data.callstart.replace(" UTC","")),l=null;i.startTime&&(l=moment.utc(i.startTime),a=moment.duration(l.diff(o))),o=o.format("YYYY-MM-DD HH:mm:ss UTC"),l=l?l.format("YYYY-MM-DD HH:mm:ss UTC"):null,a=0!=a?a.asSeconds():0;var s="",r="";"inbound"==i.data.calldirection?s="<"+i.remoteIdentity.uri.user+"> "+i.remoteIdentity.displayName:"outbound"==i.data.calldirection&&(r=i.remoteIdentity.uri.user);var d=i.data.withvideo?"("+lang.with_video+")":"",c="inbound"==i.data.calldirection?lang.you_received_a_call_from+" "+s+" "+d:lang.you_made_a_call_to+" "+r+" "+d;if(n.push({Message:c,TimeStr:o}),l){var u="inbound"==i.data.calldirection?lang.you_answered_after+" "+a+" "+lang.seconds_plural:lang.they_answered_after+" "+a+" "+lang.seconds_plural;n.push({Message:u,TimeStr:l})}var p=i.data.transfer?i.data.transfer:[];$.each(p,(function(e,t){var i="Blind"==t.type?lang.you_started_a_blind_transfer_to+" "+t.to+". ":lang.you_started_an_attended_transfer_to+" "+t.to+". ";t.accept&&1==t.accept.complete?i+=lang.the_call_was_completed:""!=t.accept.disposition&&(i+=lang.the_call_was_not_completed+" ("+t.accept.disposition+")"),n.push({Message:i,TimeStr:t.transferTime})}));var g=i.data.mute?i.data.mute:[];$.each(g,(function(e,t){n.push({Message:"mute"==t.event?lang.you_put_the_call_on_mute:lang.you_took_the_call_off_mute,TimeStr:t.eventTime})}));var m=i.data.hold?i.data.hold:[];$.each(m,(function(e,t){n.push({Message:"hold"==t.event?lang.you_put_the_call_on_hold:lang.you_took_the_call_off_hold,TimeStr:t.eventTime})}));var f=i.data.recordings?i.data.recordings:[];$.each(f,(function(e,t){var i=lang.call_is_being_recorded;t.startTime!=t.stopTime&&(i+="("+lang.now_stopped+")"),n.push({Message:i,TimeStr:t.startTime})}));var v=i.data.confcalls?i.data.confcalls:[];$.each(v,(function(e,t){var i=lang.you_started_a_conference_call_to+" "+t.to+". ";t.accept&&1==t.accept.complete?i+=lang.the_call_was_completed:""!=t.accept.disposition&&(i+=lang.the_call_was_not_completed+" ("+t.accept.disposition+")"),n.push({Message:i,TimeStr:t.startTime})})),n.sort((function(e,t){var i=moment.utc(e.TimeStr.replace(" UTC","")),n=moment.utc(t.TimeStr.replace(" UTC",""));return i.isSameOrAfter(n,"second")?-1:1})),$.each(n,(function(t,i){var n="<table class=timelineMessage cellspacing=0 cellpadding=0><tr>";n+="<td class=timelineMessageArea>",n+='<div class=timelineMessageDate><i class="fa fa-circle timelineMessageDot"></i>'+moment.utc(i.TimeStr.replace(" UTC","")).local().format(DisplayTimeFormat)+"</div>",n+="<div class=timelineMessageText>"+i.Message+"</div>",n+="</td>",n+="</tr></table>",$("#line-"+e+"-CallDetails").prepend(n)}))}}var Buddy=function(e,t,i,n,a,o,l,s,r,d){this.type=e,this.identity=t,this.CallerIDName=i,this.Email=d,this.Desc=r,this.ExtNo=n,this.MobileNumber=a,this.ContactNumber1=o,this.ContactNumber2=l,this.lastActivity=s,this.devState="dotOffline",this.presence="Unknown",this.missed=0,this.IsSelected=!1,this.imageObjectURL=""};function InitUserBuddies(){return localDB.setItem(profileUserID+"-Buddies",JSON.stringify({TotalRows:0,DataCollection:[]})),JSON.parse(localDB.getItem(profileUserID+"-Buddies"))}function MakeBuddy(e,t,i,n,a,o){var l=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));null==l&&(l=InitUserBuddies());var s=null;if("contact"==e){var r=uID(),d=utcDateNow();l.DataCollection.push({Type:"contact",LastActivity:d,ExtensionNumber:"",MobileNumber:"",ContactNumber1:o,ContactNumber2:"",uID:null,cID:r,gID:null,DisplayName:a,Position:"",Description:"",Email:"",MemberCount:0}),AddBuddy(s=new Buddy("contact",r,a,"","",o,"",d,"",""),t,i)}else{r=uID(),d=utcDateNow();l.DataCollection.push({Type:"extension",LastActivity:d,ExtensionNumber:o,MobileNumber:"",ContactNumber1:"",ContactNumber2:"",uID:r,cID:null,gID:null,DisplayName:a,Position:"",Description:"",Email:"",MemberCount:0}),AddBuddy(s=new Buddy("extension",r,a,o,"","","",d,"",""),t,i,n)}return l.TotalRows=l.DataCollection.length,localDB.setItem(profileUserID+"-Buddies",JSON.stringify(l)),s}function UpdateBuddyCalerID(e,t){e.CallerIDName=t;var i=e.identity,n=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));null!=n&&($.each(n.DataCollection,(function(e,n){if(n.uID==i||n.cID==i||n.gID==i)return n.DisplayName=t,!1})),localDB.setItem(profileUserID+"-Buddies",JSON.stringify(n))),UpdateBuddyList()}function AddBuddy(e,t,i,n){Buddies.push(e),1==t&&UpdateBuddyList(),AddBuddyMessageStream(e),1==n&&SubscribeBuddy(e),1==i&&SelectBuddy(e.identity)}function PopulateBuddyList(){console.log("Clearing Buddies..."),Buddies=new Array,console.log("Adding Buddies...");var e=JSON.parse(localDB.getItem(profileUserID+"-Buddies"));null!=e&&(console.log("Total Buddies: "+e.TotalRows),$.each(e.DataCollection,(function(e,t){if("extension"==t.Type)AddBuddy(new Buddy("extension",t.uID,t.DisplayName,t.ExtensionNumber,t.MobileNumber,t.ContactNumber1,t.ContactNumber2,t.LastActivity,t.Position,t.Email),!1,!1);else if("contact"==t.Type){AddBuddy(new Buddy("contact",t.cID,t.DisplayName,"",t.MobileNumber,t.ContactNumber1,t.ContactNumber2,t.LastActivity,t.Description,t.Email),!1,!1)}else if("group"==t.Type){AddBuddy(new Buddy("group",t.gID,t.DisplayName,t.ExtensionNumber,"","","",t.LastActivity,t.MemberCount+" member(s)",t.Email),!1,!1)}})),console.log("Updating Buddy List..."),UpdateBuddyList())}function UpdateBuddyList(){var e=$("#txtFindBuddy").val();$("#myContacts").empty();for(var t=0;t<Lines.length;t++){var i=Lines[t].IsSelected?"buddySelected":"buddy";null!=Lines[t].SipSession&&(i=Lines[t].SipSession.local_hold?"buddyActiveCallHollding":"buddyActiveCall");var n='<div id="line-'+Lines[t].LineNumber+'" class='+i+" onclick=\"SelectLine('"+Lines[t].LineNumber+"')\">";n+="<div class=lineIcon>"+(t+1)+"</div>",n+='<div class=contactNameText><i class="fa fa-phone"></i> '+lang.line+" "+(t+1)+"</div>",n+='<div id="Line-'+Lines[t].ExtNo+'-datetime" class=contactDate> </div>',n+="<div class=presenceText>"+Lines[t].DisplayName+" <"+Lines[t].DisplayNumber+"></div>",n+="</div>",Lines[t].SipSession&&1!=Lines[t].SipSession.data.earlyReject&&($("#myContacts").append(n))}Buddies.sort((function(e,t){var i=moment.utc(e.lastActivity.replace(" UTC","")),n=moment.utc(t.lastActivity.replace(" UTC",""));return i.isSameOrAfter(n,"second")?-1:1}));for(var a=0;a<Buddies.length;a++){var o=Buddies[a];if(e&&e.length>=1){var l=!1;if(o.CallerIDName.toLowerCase().indexOf(e.toLowerCase())>-1&&(l=!0),o.ExtNo.toLowerCase().indexOf(e.toLowerCase())>-1&&(l=!0),o.Desc.toLowerCase().indexOf(e.toLowerCase())>-1&&(l=!0),!l)continue}var s=moment.utc(),r=moment.utc(o.lastActivity.replace(" UTC","")),d="";d=r.isSame(s,"day")?r.local().format(DisplayTimeFormat):r.local().format(DisplayDateFormat);i=o.IsSelected?"buddySelected":"buddy";if("extension"==o.type){var c=o.presence;"Unknown"==c&&(c=lang.state_unknown),"Not online"==c&&(c=lang.state_not_online),"Ready"==c&&(c=lang.state_ready),"On the phone"==c&&(c=lang.state_on_the_phone),"Ringing"==c&&(c=lang.state_ringing),"On hold"==c&&(c=lang.state_on_hold),"Unavailable"==c&&(c=lang.state_unavailable);n='<div id="contact-'+o.identity+'" class='+i+" onmouseenter=\"ShowBuddyDial(this, '"+o.identity+"')\" onmouseleave=\"HideBuddyDial(this, '"+o.identity+"')\" onclick=\"SelectBuddy('"+o.identity+"', 'extension')\">";n+='<span id="contact-'+o.identity+'-devstate" class="'+o.devState+'"></span>',1==getDbItem("useRoundcube","")&&""!=o.Email&&null!=o.Email&&void 0!==o.Email&&(n+='<span id="contact-'+o.identity+'-email" class=quickDial style="right: 66px; display:none" title=\''+lang.send_email+"' onclick=\"ComposeEmail('"+o.identity+'\', this, event)"><i class="fa fa-envelope-o" aria-hidden="true"></i></span>'),EnableVideoCalling?(n+='<span id="contact-'+o.identity+'-audio-dial" class=quickDial style="right: 44px; display:none" title=\''+lang.audio_call+"' onclick=\"QuickDialAudio('"+o.identity+'\', this, event)"><i class="fa fa-phone"></i></span>',n+='<span id="contact-'+o.identity+'-video-dial" class=quickDial style="right: 23px; display:none" title=\''+lang.video_call+"' onclick=\"QuickDialVideo('"+o.identity+"', '"+o.ExtNo+'\', event)"><i class="fa fa-video-camera"></i></span>'):n+='<span id="contact-'+o.identity+'-audio-dial" class=quickDial style="right: 23px; display:none" title=\''+lang.audio_call+"' onclick=\"QuickDialAudio('"+o.identity+'\', this, event)"><i class="fa fa-phone"></i></span>',o.missed&&o.missed>0?n+='<span id="contact-'+o.identity+'-missed" class=missedNotifyer>'+o.missed+"</span>":n+='<span id="contact-'+o.identity+'-missed" class=missedNotifyer style="display:none">'+o.missed+"</span>",n+="<div class=buddyIcon onclick=\"EditBuddyWindow('"+o.identity+"')\" style=\"background-image: url('"+getPicture(o.identity)+'\')" title="Edit Contact"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></div>',n+='<div class=contactNameText><i class="fa fa-phone-square"></i> '+o.ExtNo+" - "+o.CallerIDName+"</div>",n+='<div id="contact-'+o.identity+'-datetime" class=contactDate>'+d+"</div>",n+='<div id="contact-'+o.identity+'-presence" class=presenceText>'+c+"</div>",n+="</div>",$("#myContacts").append(n)}else if("contact"==o.type){n='<div id="contact-'+o.identity+'" class='+i+" onmouseenter=\"ShowBuddyDial(this, '"+o.identity+"')\" onmouseleave=\"HideBuddyDial(this, '"+o.identity+"')\" onclick=\"SelectBuddy('"+o.identity+"', 'contact')\">";1==getDbItem("useRoundcube","")&&""!=o.Email&&null!=o.Email&&void 0!==o.Email&&(n+='<span id="contact-'+o.identity+'-email" class=quickDial style="right: 44px; display:none" title=\''+lang.send_email+"' onclick=\"ComposeEmail('"+o.identity+'\', this, event)"><i class="fa fa-envelope-o" aria-hidden="true"></i></span>'),n+='<span id="contact-'+o.identity+'-audio-dial" class=quickDial style="right: 23px; display:none" title=\''+lang.audio_call+"' onclick=\"QuickDialAudio('"+o.identity+'\', this, event)"><i class="fa fa-phone"></i></span>',o.missed&&o.missed>0?n+='<span id="contact-'+o.identity+'-missed" class=missedNotifyer>'+o.missed+"</span>":n+='<span id="contact-'+o.identity+'-missed" class=missedNotifyer style="display:none">'+o.missed+"</span>",n+="<div class=buddyIcon onclick=\"EditBuddyWindow('"+o.identity+"')\" style=\"background-image: url('"+getPicture(o.identity,"contact")+'\')" title="Edit Contact"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></div>',n+='<div class=contactNameText><i class="fa fa-address-card"></i> '+o.CallerIDName+"</div>",n+='<div id="contact-'+o.identity+'-datetime" class=contactDate>'+d+"</div>",n+="<div class=presenceText>"+o.Desc+"</div>",n+="</div>",$("#myContacts").append(n)}else if("group"==o.type){n='<div id="contact-'+o.identity+'" class='+i+" onmouseenter=\"ShowBuddyDial(this, '"+o.identity+"')\" onmouseleave=\"HideBuddyDial(this, '"+o.identity+"')\" onclick=\"SelectBuddy('"+o.identity+"', 'group')\">";1==getDbItem("useRoundcube","")&&""!=o.Email&&null!=o.Email&&void 0!==o.Email&&(n+='<span id="contact-'+o.identity+'-email" class=quickDial style="right: 44px; display:none" title=\''+lang.send_email+"' onclick=\"ComposeEmail('"+o.identity+'\', this, event)"><i class="fa fa-envelope-o" aria-hidden="true"></i></span>'),n+='<span id="contact-'+o.identity+'-audio-dial" class=quickDial style="right: 23px; display:none" title=\''+lang.audio_call+"' onclick=\"QuickDialAudio('"+o.identity+'\', this, event)"><i class="fa fa-phone"></i></span>',o.missed&&o.missed>0?n+='<span id="contact-'+o.identity+'-missed" class=missedNotifyer>'+o.missed+"</span>":n+='<span id="contact-'+o.identity+'-missed" class=missedNotifyer style="display:none">'+o.missed+"</span>",n+="<div class=buddyIcon onclick=\"EditBuddyWindow('"+o.identity+"')\" style=\"background-image: url('"+getPicture(o.identity,"group")+'\')" title="Edit Contact"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></div>',n+='<div class=contactNameText><i class="fa fa-users"></i> '+o.CallerIDName+"</div>",n+='<div id="contact-'+o.identity+'-datetime" class=contactDate>'+d+"</div>",n+="<div class=presenceText>"+o.Desc+"</div>",n+="</div>",$("#myContacts").append(n)}}}function AddBuddyMessageStream(e){var t='<table id="stream-'+e.identity+'" class=stream cellspacing=5 cellpadding=0>';if(t+='<tr><td class=streamSection style="height: 48px;">',t+='<div style="float:left; margin:8.7px 0px 0px 8.7px; width: 38px; height:38px; line-height:38px;">',t+='<button id="contact-'+e.identity+'-btn-back" onclick="CloseBuddy(\''+e.identity+'\')" class=roundButtons title="'+lang.back+'"><i class="fa fa-chevron-left"></i></button> ',t+="</div>",t+='<div class=contact style="float: left; position: absolute; left: 47px; right: 190px;" onclick="ShowBuddyProfileMenu(\''+e.identity+"', this, '"+e.type+"')\">","extension"==e.type&&(t+='<span id="contact-'+e.identity+'-devstate-main" class="'+e.devState+'"></span>'),"extension"==e.type?t+='<div id="contact-'+e.identity+'-picture-main" class=buddyIcon style="background-image: url(\''+getPicture(e.identity)+"')\"></div>":"contact"==e.type?t+="<div class=buddyIcon style=\"background-image: url('"+getPicture(e.identity,"contact")+"')\"></div>":"group"==e.type&&(t+="<div class=buddyIcon style=\"background-image: url('"+getPicture(e.identity,"group")+"')\"></div>"),"extension"==e.type?t+='<div class=contactNameText style="margin-right: 0px;"><i class="fa fa-phone-square"></i> '+e.ExtNo+" - "+e.CallerIDName+"</div>":"contact"==e.type?t+='<div class=contactNameText style="margin-right: 0px;"><i class="fa fa-address-card"></i> '+e.CallerIDName+"</div>":"group"==e.type&&(t+='<div class=contactNameText style="margin-right: 0px;"><i class="fa fa-users"></i> '+e.CallerIDName+"</div>"),"extension"==e.type){var i=e.presence;"Unknown"==i&&(i=lang.state_unknown),"Not online"==i&&(i=lang.state_not_online),"Ready"==i&&(i=lang.state_ready),"On the phone"==i&&(i=lang.state_on_the_phone),"Ringing"==i&&(i=lang.state_ringing),"On hold"==i&&(i=lang.state_on_hold),"Unavailable"==i&&(i=lang.state_unavailable),t+='<div id="contact-'+e.identity+'-presence-main" class=presenceText>'+i+"</div>"}else t+='<div id="contact-'+e.identity+'-presence-main" class=presenceText>'+e.Desc+"</div>";t+="</div>",t+='<div style="float:right; line-height:46px; margin:3.2px 5px 0px 0px;">',t+='<button id="contact-'+e.identity+'-btn-audioCall" onclick="AudioCallMenu(\''+e.identity+'\', this)" class=roundButtons title="'+lang.audio_call+'"><i class="fa fa-phone"></i></button> ',"extension"==e.type&&EnableVideoCalling&&(t+='<button id="contact-'+e.identity+"-btn-videoCall\" onclick=\"DialByLine('video', '"+e.identity+"', '"+e.ExtNo+'\');" class=roundButtons title="'+lang.video_call+'"><i class="fa fa-video-camera"></i></button> '),t+='<button id="contact-'+e.identity+'-btn-search" onclick="FindSomething(\''+e.identity+'\')" class=roundButtons title="'+lang.find_something+'"><i class="fa fa-search"></i></button> ',"extension"==e.type&&(t+='<button id="contact-'+e.identity+'-btn-download-chat" onclick="DownloadChatText(\''+e.identity+'\')" class=roundButtons title="'+lang.save_chat_text+'"><i class="fa fa-download" aria-hidden="true"></i></button> '),t+='<button id="contact-'+e.identity+'-btn-remove" onclick="RemoveBuddy(\''+e.identity+'\')" class=roundButtons title="'+lang.remove_contact+'"><i class="fa fa-trash"></i></button> ',t+="</div>",t+='<div style="clear:both; height:0px"></div>',t+='<div id="contact-'+e.identity+'-calling">',t+='<div id="contact-'+e.identity+'-timer" style="float: right; margin-top: 4px; margin-right: 10px; color: #575757; display:none;"></div>',t+='<div id="contact-'+e.identity+'-msg" class=callStatus style="display:none">...</div>',t+='<div id="contact-'+e.identity+'-AnswerCall" class=answerCall style="display:none">',t+="<div>",t+="<button onclick=\"AnswerAudioCall('"+e.identity+'\')" class=answerButton><i class="fa fa-phone"></i> '+lang.answer_call+"</button> ","extension"==e.type&&EnableVideoCalling&&(t+='<button id="contact-'+e.identity+'-answer-video" onclick="AnswerVideoCall(\''+e.identity+'\')" class=answerButton><i class="fa fa-video-camera"></i> '+lang.answer_call_with_video+"</button> "),t+="<button onclick=\"RejectCall('"+e.identity+'\')" class=hangupButton><i class="fa fa-phone"></i> '+lang.reject_call+"</button> ",t+="</div>",t+="</div>",t+="</div>",t+='<div id="contact-'+e.identity+'-search" style="margin-top:6px; display:none">',t+='<span class=searchClean style="width:100%; margin-left:9px;"><input type=text style="width:40%;margin-bottom:5px;" autocomplete=none oninput=SearchStream(this,\''+e.identity+"') placeholder=\""+lang.find_something_in_the_message_stream+'"></span>',t+="</div>",t+="</td></tr>",t+='<tr><td class="streamSection streamSectionBackground">',t+='<div id="contact-'+e.identity+'-ChatHistory" class="chatHistory cleanScroller" ondragenter="setupDragDrop(event, \''+e.identity+"')\" ondragover=\"setupDragDrop(event, '"+e.identity+"')\" ondragleave=\"cancelDragDrop(event, '"+e.identity+"')\" ondrop=\"onFileDragDrop(event, '"+e.identity+"')\">",t+="</div>",t+="</td></tr>","extension"!=e.type&&"group"!=e.type||!EnableTextMessaging||(t+='<tr><td id=sendChatMessageSection class=streamSection style="height:110px">',t+='<div id="contact-'+e.identity+'-imagePastePreview" class=sendImagePreview style="display:none" tabindex=0></div>',t+='<div id="contact-'+e.identity+'-fileShare" style="display:none">',t+='<input type=file multiple onchange="console.log(this)" />',t+="</div>",t+='<div id="contact-'+e.identity+'-audio-recording" style="display:none"></div>',t+='<div id="contact-'+e.identity+'-video-recording" style="display:none"></div>',t+='<div id="contact-'+e.identity+'-emoji-menu" style="display:none" class="EmojiMenu"></div>',t+="<table class=sendMessageContainer cellpadding=0 cellspacing=0><tr>",t+='<td><textarea id="contact-'+e.identity+'-ChatMessage" class="chatMessage" placeholder="'+lang.type_your_message_here+'" onkeydown="chatOnkeydown(event, this,\''+e.identity+"')\" onpaste=\"chatOnbeforepaste(event, this,'"+e.identity+"')\"></textarea></td>",t+='<td style="width:40px;padding-top:4px;"><button onclick="SendChatMessage(\''+e.identity+'\')" class=roundButtonsSpec title="'+lang.send_chat_message+'"><i class="fa fa-paper-plane-o" aria-hidden="true"></i></button>',t+="<button onclick=\"ShowEmojiBar('"+e.identity+'\')" class=roundButtonsSpec title="'+lang.select_expression+'"><i class="fa fa-smile-o"></i></button>',t+="<button onclick=\"SendFile('"+e.identity+'\')" class=roundButtonsSpec title="'+lang.send_file+'"><i class="fa fa-file-text-o"></i></button></td>',t+="</tr></table>",t+="</td></tr>"),t+="</table>",$("#rightContent").append(t)}function RemoveBuddyMessageStream(e){CloseBuddy(e.identity),UpdateBuddyList(),$("#stream-"+e.identity).remove();var t=JSON.parse(localDB.getItem(e.identity+"-stream"));localDB.removeItem(e.identity+"-stream");var i=JSON.parse(localDB.getItem(profileUserID+"-Buddies")),n=0;$.each(i.DataCollection,(function(t,i){if(i.uID==e.identity||i.cID==e.identity||i.gID==e.identity)return n=t,!1})),i.DataCollection.splice(n,1),i.TotalRows=i.DataCollection.length,localDB.setItem(profileUserID+"-Buddies",JSON.stringify(i)),localDB.removeItem("img-"+e.identity+"-extension"),localDB.removeItem("img-"+e.identity+"-contact"),localDB.removeItem("img-"+e.identity+"-group"),t&&t.DataCollection&&t.DataCollection.length>=1&&DeleteCallRecordings(e.identity,t),DeleteQosData(e.identity)}function DeleteCallRecordings(e,t){var i=window.indexedDB.open("CallRecordings");i.onerror=function(e){console.error("IndexDB Request Error:",e)},i.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.")},i.onsuccess=function(e){console.log("IndexDB connected to CallRecordings");var i=e.target.result;0!=i.objectStoreNames.contains("Recordings")?(i.onerror=function(e){console.error("IndexDB Error:",e)},$.each(t.DataCollection,(function(e,t){t.Recordings&&t.Recordings.length&&$.each(t.Recordings,(function(e,t){console.log("Deleting Call Recording: ",t.uID);var n=i.transaction(["Recordings"],"readwrite").objectStore("Recordings");try{n.delete(t.uID).onsuccess=function(e){console.log("Call Recording Deleted: ",t.uID)}}catch(e){console.log("Call Recording Delete failed: ",e)}}))}))):console.warn("IndexDB CallRecordings.Recordings does not exists")}}function MakeUpName(){var e=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],t="";t+=e[Math.floor(Math.random()*e.length)];for(var i=0;i<Math.floor(12*Math.random())+4;i++)t+=e[Math.floor(Math.random()*e.length)].toLowerCase();t+=" ",t+=e[Math.floor(Math.random()*e.length)];for(i=0;i<Math.floor(12*Math.random())+4;i++)t+=e[Math.floor(Math.random()*e.length)].toLowerCase();return t}function MakeUpNumber(){for(var e=["0","1","2","3","4","5","6","7","8","9","0"],t="0",i=0;i<9;i++)t+=e[Math.floor(Math.random()*e.length)];return t}function MakeUpBuddies(e){for(var t=0;t<e;t++){AddBuddy(new Buddy("contact",uID(),MakeUpName(),"","",MakeUpNumber(),"",utcDateNow(),"Testing",""),!1,!1)}UpdateBuddyList()}function SelectBuddy(e){$("#roundcubeFrame").remove(),$(".streamSelected").each((function(){$(this).show()}));var t=FindBuddyByIdentity(e);if(null!=t){for(var i=0;i<Buddies.length;i++)if(1==Buddies[i].IsSelected&&Buddies[i].identity==e)return;console.log("Selecting Buddy: "+e),selectedBuddy=t,$(".streamSelected").each((function(){$(this).prop("class","stream")})),$("#stream-"+e).prop("class","streamSelected");for(var n=0;n<Lines.length;n++){var a="buddy";null!=Lines[n].SipSession&&(a=Lines[n].SipSession.local_hold?"buddyActiveCallHollding":"buddyActiveCall"),$("#line-"+Lines[n].LineNumber).prop("class",a),Lines[n].IsSelected=!1}ClearMissedBadge(e);for(i=0;i<Buddies.length;i++){a=Buddies[i].identity==e?"buddySelected":"buddy";$("#contact-"+Buddies[i].identity).prop("class",a),$("#contact-"+Buddies[i].identity+"-ChatHistory").empty(),Buddies[i].IsSelected=Buddies[i].identity==e}UpdateUI(),RefreshStream(t);try{$("#contact-"+e).get(0).scrollIntoViewIfNeeded()}catch(e){}localDB.setItem("SelectedBuddy",e)}}function CloseBuddy(e){$(".buddySelected").each((function(){$(this).prop("class","buddy")})),$(".streamSelected").each((function(){$(this).prop("class","stream")})),console.log("Closing Buddy: "+e);for(var t=0;t<Buddies.length;t++)Buddies[t].IsSelected=!1;selectedBuddy=null;for(var i=0;i<Lines.length;i++)Lines[i].IsSelected=!1;selectedLine=null,localDB.setItem("SelectedBuddy",null),UpdateUI()}function DownloadChatText(e){var t=FindBuddyByIdentity(e),i=t.CallerIDName,n=i.replace(" ","_"),a=t.ExtNo,o=moment().format("YYYY-MM-DD_HH-mm-ss"),l="\nRoundpin Chat With "+i+" (extension "+a+"), saved on "+moment().format("YYYY-MM-DD HH:mm:ss")+"\n\n\n\n",s="";if($("#contact-"+e+"-ChatHistory .chatMessageTable").each((function(){$(this).hasClass("theirChatMessage")?s+="\n"+i+"\n"+$(this).text()+"\n\n":s+="\nMe\n"+$(this).text()+"\n\n"})),""!=s){var r=l+s,d="Roundpin_Chat-"+n+"_"+o,c=document.createElement("a");c.setAttribute("download",d),c.setAttribute("href","data:text/plain;charset=utf-8,"+encodeURIComponent(r)),c.click()}else alert("There is no chat text to save ! ")}function RemoveBuddy(e){var t=FindBuddyByIdentity(e).CallerIDName;Confirm(lang.confirm_remove_buddy,lang.remove_buddy,(function(){for(var i=0;i<Buddies.length;i++)if(Buddies[i].identity==e){RemoveBuddyMessageStream(Buddies[i]),UnsubscribeBuddy(Buddies[i]),Buddies.splice(i,1);break}deleteBuddyFromSqldb(t),UpdateBuddyList()}))}function FindBuddyByDid(e){for(var t=0;t<Buddies.length;t++)if(Buddies[t].ExtNo==e||Buddies[t].MobileNumber==e||Buddies[t].ContactNumber1==e||Buddies[t].ContactNumber2==e)return Buddies[t];return null}function FindBuddyByExtNo(e){for(var t=0;t<Buddies.length;t++)if("extension"==Buddies[t].type&&Buddies[t].ExtNo==e)return Buddies[t];return null}function FindBuddyByNumber(e){for(var t=0;t<Buddies.length;t++)if(Buddies[t].MobileNumber==e||Buddies[t].ContactNumber1==e||Buddies[t].ContactNumber2==e)return Buddies[t];return null}function FindBuddyByIdentity(e){for(var t=0;t<Buddies.length;t++)if(Buddies[t].identity==e)return Buddies[t];return null}function SearchStream(e,t){var i=e.value,n=FindBuddyByIdentity(t);""==i?(console.log("Restore Stream"),RefreshStream(n)):RefreshStream(n,i)}function RefreshStream(e,t){$("#contact-"+e.identity+"-ChatHistory").empty();var i=JSON.parse(localDB.getItem(e.identity+"-stream"));null!=i&&null!=i.DataCollection&&(i.DataCollection.sort((function(e,t){var i=moment.utc(e.ItemDate.replace(" UTC","")),n=moment.utc(t.ItemDate.replace(" UTC",""));return i.isSameOrAfter(n,"second")?-1:1})),t&&""!=t&&(console.log("Rows without filter ("+t+"): ",i.DataCollection.length),i.DataCollection=i.DataCollection.filter((function(e){if(-1!=t.indexOf("date: ")){var i=getFilter(t,"date");if(""!=i&&-1!=e.ItemDate.indexOf(i))return!0}if(e.MessageData&&e.MessageData.length>1){if(-1!=e.MessageData.toLowerCase().indexOf(t.toLowerCase()))return!0;if(-1!=t.toLowerCase().indexOf(e.MessageData.toLowerCase()))return!0}if("MSG"==e.ItemType);else if("CDR"==e.ItemType){if(e.Tags&&e.Tags.length>1){var n=getFilter(t,"tag");if(""!=n&&1==e.Tags.some((function(e){return-1!=n.toLowerCase().indexOf(e.value.toLowerCase())||-1!=e.value.toLowerCase().indexOf(n.toLowerCase())})))return!0}}else"FILE"==e.ItemType||e.ItemType;return!1})),console.log("Rows After Filter: ",i.DataCollection.length)),i.DataCollection.length>StreamBuffer&&(console.log("Rows:",i.DataCollection.length," (will be trimed to "+StreamBuffer+")"),i.DataCollection.splice(StreamBuffer)),$.each(i.DataCollection,(function(t,i){var n=moment.utc(i.ItemDate.replace(" UTC","")).isSame(moment.utc(),"day"),a=" "+moment.utc(i.ItemDate.replace(" UTC","")).local().calendar(null,{sameElse:DisplayDateFormat});if(n&&(a=" "+moment.utc(i.ItemDate.replace(" UTC","")).local().format(DisplayTimeFormat)),"MSG"==i.ItemType){var o='<i class="fa fa-question-circle-o SendingMessage"></i>';1==i.Sent&&(o='<i class="fa fa-check SentMessage"></i>'),0==i.Sent&&(o='<i class="fa fa-exclamation-circle FailedMessage"></i>'),i.Delivered&&(o+='<i class="fa fa-check DeliveredMessage"></i>');var l=(d=ReformatMessage(i.MessageData)).length>1e3;if(i.SrcUserId==profileUserID){if(0!=d.length){var s='<table class="ourChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr>';s+='<td class=ourChatMessageText onmouseenter="ShowChatMenu(this)" onmouseleave="HideChatMenu(this)">',s+="<span onclick=\"ShowMessgeMenu(this,'MSG','"+i.ItemId+"', '"+e.identity+'\')" class=chatMessageDropdown style="display:none"><i class="fa fa-chevron-down"></i></span>',s+="<div id=msg-text-"+i.ItemId+' class=messageText style="'+(l?"max-height:190px; overflow:hidden":"")+'">'+d+"</div>",l&&(s+="<div id=msg-readmore-"+i.ItemId+" class=messageReadMore><span onclick=\"ExpandMessage(this,'"+i.ItemId+"', '"+e.identity+"')\">"+lang.read_more+"</span></div>"),s+="<div class=messageDate>"+a+" "+o+"</div>",s+="</td>",s+="</tr></table>"}}else{if(0!=d.length){s='<table class="theirChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr>';s+='<td class=theirChatMessageText onmouseenter="ShowChatMenu(this)" onmouseleave="HideChatMenu(this)">',s+="<span onclick=\"ShowMessgeMenu(this,'MSG','"+i.ItemId+"', '"+e.identity+'\')" class=chatMessageDropdown style="display:none"><i class="fa fa-chevron-down"></i></span>',"group"==e.type&&(s+="<div class=messageDate></div>"),s+="<div id=msg-text-"+i.ItemId+' class=messageText style="'+(l?"max-height:190px; overflow:hidden":"")+'">'+d+"</div>",l&&(s+="<div id=msg-readmore-"+i.ItemId+" class=messageReadMore><span onclick=\"ExpandMessage(this,'"+i.ItemId+"', '"+e.identity+"')\">"+lang.read_more+"</span></div>"),s+="<div class=messageDate>"+a+"</div>",s+="</td>",s+="</tr></table>"}}0!=d.length&&$("#contact-"+e.identity+"-ChatHistory").prepend(s)}else if("CDR"==i.ItemType){var r=i.Billsec>0?"green":"red",d="",c="<span id=cdr-flagged-"+i.CdrId+' style="'+(i.Flagged?"":"display:none")+'">';c+='<i class="fa fa-flag FlagCall"></i> ',c+="</span>";var u="";i.MessageData&&(u=i.MessageData),i.Tags||(i.Tags=[]);var p="<ul id=cdr-tags-"+i.CdrId+' class=tags style="'+(i.Tags&&i.Tags.length>0?"":"display:none")+'">';$.each(i.Tags,(function(t,n){p+="<li onclick=\"TagClick(this, '"+i.CdrId+"', '"+e.identity+"')\">"+n.value+"</li>"})),p+="<li class=tagText><input maxlength=24 type=text onkeypress=\"TagKeyPress(event, this, '"+i.CdrId+"', '"+e.identity+'\')" onfocus="TagFocus(this)"></li>',p+="</ul>",d+='<i class="fa '+(i.WithVideo?"fa-video-camera":"fa-phone")+'" style="color:'+r+'"></i>';var g=i.WithVideo?lang.a_video_call:lang.an_audio_call,m="";if(i.Recordings&&i.Recordings.length>=1&&$.each(i.Recordings,(function(t,n){if(n.uID){var a=moment.utc(n.startTime.replace(" UTC","")).local(),o=moment.utc(n.stopTime.replace(" UTC","")).local(),l=moment.duration(o.diff(a));if(m+="<div class=callRecording>",i.WithVideo)if(n.Poster){n.Poster.width,n.Poster.height;var s=n.Poster.posterBase64;m+='<div><IMG src="'+s+'"><button onclick="PlayVideoCallRecording(this, \''+i.CdrId+"', '"+n.uID+'\')" class=videoPoster><i class="fa fa-play"></i></button></div>'}else m+="<div><button onclick=\"PlayVideoCallRecording(this, '"+i.CdrId+"', '"+n.uID+"', '"+e.identity+'\')"><i class="fa fa-video-camera"></i></button></div>';else m+="<div><button onclick=\"PlayAudioCallRecording(this, '"+i.CdrId+"', '"+n.uID+"', '"+e.identity+'\')"><i class="fa fa-play"></i></button></div>';m+="<div>"+lang.started+": "+a.format(DisplayTimeFormat)+' <i class="fa fa-long-arrow-right"></i> '+lang.stopped+": "+o.format(DisplayTimeFormat)+"</div>",m+="<div>"+lang.recording_duration+": "+formatShortDuration(l.asSeconds())+"</div>",m+="<div>",m+='<span id="cdr-video-meta-width-'+i.CdrId+"-"+n.uID+'"></span>',m+='<span id="cdr-video-meta-height-'+i.CdrId+"-"+n.uID+'"></span>',m+='<span id="cdr-media-meta-size-'+i.CdrId+"-"+n.uID+'"></span>',m+='<span id="cdr-media-meta-codec-'+i.CdrId+"-"+n.uID+'"></span>',m+="</div>",m+="</div>"}})),i.SrcUserId==profileUserID){"0"==i.Billsec?d+=" "+lang.you_tried_to_make+" "+g+" ("+i.ReasonText+").":d+=" "+lang.you_made+" "+g+", "+lang.and_spoke_for+" "+formatDuration(i.Billsec)+".";s='<table class="ourChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr>';s+='<td style="padding-right:4px;">'+c+"</td>",s+='<td class=ourChatMessageText onmouseenter="ShowChatMenu(this)" onmouseleave="HideChatMenu(this)">',s+="<span onClick=\"ShowMessgeMenu(this,'CDR','"+i.CdrId+"', '"+e.identity+'\')" class=chatMessageDropdown style="display:none"><i class="fa fa-chevron-down"></i></span>',s+="<div>"+d+"</div>",s+="<div>"+p+"</div>",s+="<div id=cdr-comment-"+i.CdrId+" class=cdrComment>"+u+"</div>",s+="<div class=callRecordings>"+m+"</div>",s+="<div class=messageDate>"+a+"</div>",s+="</td>",s+="</tr></table>"}else{"0"==i.Billsec?d+=" "+lang.you_missed_a_call+" ("+i.ReasonText+").":d+=" "+lang.you_recieved+" "+g+", "+lang.and_spoke_for+" "+formatDuration(i.Billsec)+".";s='<table class="theirChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr>';s+='<td class=theirChatMessageText onmouseenter="ShowChatMenu(this)" onmouseleave="HideChatMenu(this)">',s+="<span onClick=\"ShowMessgeMenu(this,'CDR','"+i.CdrId+"', '"+e.identity+'\')" class=chatMessageDropdown style="display:none"><i class="fa fa-chevron-down"></i></span>',s+='<div style="text-align:left">'+d+"</div>",s+="<div>"+p+"</div>",s+="<div id=cdr-comment-"+i.CdrId+" class=cdrComment>"+u+"</div>",s+="<div class=callRecordings>"+m+"</div>",s+="<div class=messageDate> "+a+"</div>",s+="</td>",s+='<td style="padding-left:4px">'+c+"</td>",s+="</tr></table>"}$("#contact-"+e.identity+"-ChatHistory").prepend(s)}else if("FILE"==i.ItemType)if(i.SrcUserId==profileUserID){var f='<table class="ourChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr>';f+="<td><div class='sentFileChatRect'>Download file<br><a href='download-sent-chat-file.php?s_ajax_call="+validateSToken+"&destSipUser="+i.Dst+"&sentFlNm="+i.SentFileName+"' target='_blank'>"+i.SentFileName+"</a>",f+='<span style="display:block;width:100%;height:10px;"></span><div class="messageDate">'+a+"</div></div>",f+="</td>",f+="</tr></table>",$("#contact-"+e.identity+"-ChatHistory").prepend(f),$("#sendFileLoader").remove()}else{var v='<table class="theirChatMessage chatMessageTable" cellspacing=0 cellpadding=0><tr>';v+="<td><div class='recFileChatRect'>Download file<br><a href='download-rec-chat-file.php?s_ajax_call="+validateSToken+"&recSipUser="+i.Dst+"&recFlNm="+i.ReceivedFileName+"' target='_blank'>"+i.ReceivedFileName+"</a>",v+='<span style="display:block;width:100%;height:10px;"></span><div class="messageDate">'+a+"</div></div>",v+="</td>",v+="</tr></table>",$("#contact-"+e.identity+"-ChatHistory").prepend(v)}else i.ItemType})),updateScroll(e.identity),window.setTimeout((function(){updateScroll(e.identity)}),300))}function ShowChatMenu(e){$(e).children("span").show()}function HideChatMenu(e){$(e).children("span").hide()}function ExpandMessage(e,t,i){$("#msg-text-"+t).css("max-height",""),$("#msg-text-"+t).css("overflow",""),$("#msg-readmore-"+t).remove(),$.jeegoopopup.close()}function ShowBuddyDial(e,t){$("#contact-"+t+"-email").show(),$("#contact-"+t+"-audio-dial").show(),$("#contact-"+t+"-video-dial").show()}function HideBuddyDial(e,t){$("#contact-"+t+"-email").hide(),$("#contact-"+t+"-audio-dial").hide(),$("#contact-"+t+"-video-dial").hide()}function QuickDialAudio(e,t,i){AudioCallMenu(e,t),i.stopPropagation()}function QuickDialVideo(e,t,i){i.stopPropagation(),window.setTimeout((function(){DialByLine("video",e,t)}),300)}function ExpandVideoArea(e){$("#line-"+e+"-ActiveCall").prop("class","FullScreenVideo"),$("#line-"+e+"-VideoCall").css("height","calc(100% - 100px)"),$("#line-"+e+"-VideoCall").css("margin-top","0px"),$("#line-"+e+"-preview-container").prop("class","PreviewContainer PreviewContainer_FS"),$("#line-"+e+"-stage-container").prop("class","StageContainer StageContainer_FS"),$("#line-"+e+"-restore").show(),$("#line-"+e+"-expand").hide(),$("#line-"+e+"-monitoring").hide()}function RestoreVideoArea(e){$("#line-"+e+"-ActiveCall").prop("class",""),$("#line-"+e+"-VideoCall").css("height",""),$("#line-"+e+"-VideoCall").css("margin-top","10px"),$("#line-"+e+"-preview-container").prop("class","PreviewContainer"),$("#line-"+e+"-stage-container").prop("class","StageContainer"),$("#line-"+e+"-restore").hide(),$("#line-"+e+"-expand").show(),$("#line-"+e+"-monitoring").show()}function MuteSession(e){$("#line-"+e+"-btn-Unmute").show(),$("#line-"+e+"-btn-Mute").hide();var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;i.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(e){"audio"==e.track.kind&&(1==e.track.IsMixedTrack?i.data.AudioSourceTrack&&"audio"==i.data.AudioSourceTrack.kind&&(console.log("Muting Audio Track : "+i.data.AudioSourceTrack.label),i.data.AudioSourceTrack.enabled=!1):(console.log("Muting Audio Track : "+e.track.label),e.track.enabled=!1))})),i.data.mute||(i.data.mute=[]),i.data.mute.push({event:"mute",eventTime:utcDateNow()}),i.data.ismute=!0,$("#line-"+e+"-msg").html(lang.call_on_mute),updateLineScroll(e),"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("mute",i)}}function UnmuteSession(e){$("#line-"+e+"-btn-Unmute").hide(),$("#line-"+e+"-btn-Mute").show();var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;i.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(e){"audio"==e.track.kind&&(1==e.track.IsMixedTrack?i.data.AudioSourceTrack&&"audio"==i.data.AudioSourceTrack.kind&&(console.log("Unmuting Audio Track : "+i.data.AudioSourceTrack.label),i.data.AudioSourceTrack.enabled=!0):(console.log("Unmuting Audio Track : "+e.track.label),e.track.enabled=!0))})),i.data.mute||(i.data.mute=[]),i.data.mute.push({event:"unmute",eventTime:utcDateNow()}),i.data.ismute=!1,$("#line-"+e+"-msg").html(lang.call_off_mute),updateLineScroll(e),"undefined"!=typeof web_hook_on_modify&&web_hook_on_modify("unmute",i)}}function ShowDtmfMenu(e,t){var i=event.pageX-90,n=event.pageY+30,a="<div id=mainDtmfDialPad>";a+='<table cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">',a+="<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '1');new Audio('sounds/dtmf.mp3').play();\"><div>1</div><span> </span></button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '2');new Audio('sounds/dtmf.mp3').play();\"><div>2</div><span>ABC</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '3');new Audio('sounds/dtmf.mp3').play();\"><div>3</div><span>DEF</span></button></td></tr>",a+="<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '4');new Audio('sounds/dtmf.mp3').play();\"><div>4</div><span>GHI</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '5');new Audio('sounds/dtmf.mp3').play();\"><div>5</div><span>JKL</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '6');new Audio('sounds/dtmf.mp3').play();\"><div>6</div><span>MNO</span></button></td></tr>",a+="<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '7');new Audio('sounds/dtmf.mp3').play();\"><div>7</div><span>PQRS</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '8');new Audio('sounds/dtmf.mp3').play();\"><div>8</div><span>TUV</span></button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '9');new Audio('sounds/dtmf.mp3').play();\"><div>9</div><span>WXYZ</span></button></td></tr>",a+="<tr><td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '*');new Audio('sounds/dtmf.mp3').play();\">*</button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '0');new Audio('sounds/dtmf.mp3').play();\">0</button></td>",a+="<td><button class=dtmfButtons onclick=\"sendDTMF('"+t+"', '#');new Audio('sounds/dtmf.mp3').play();\">#</button></td></tr>",a+="</table>",a+="</div>",$.jeegoopopup.open({html:a,width:"auto",height:"auto",left:i,top:n,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}function ShowMessgeMenu(t,i,n,a){$.jeegoopopup.close();var o=event.pageX,l=event.pageY;$(window).width()-event.pageX<t.offsetWidth+50&&(o=event.pageX-200);var s='<div id="messageMenu">';if(s+='<table id="messageMenuTable" cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">',"CDR"==i){var r=$("#cdr-flagged-"+n).is(":visible")?lang.clear_flag:lang.flag_call;s+='<tr id="CMDetails_1"><td><i class="fa fa-external-link"></i></td><td class="callDetails">'+lang.show_call_detail_record+"</td></tr>",s+='<tr id="CMDetails_2"><td><i class="fa fa-tags"></i></td><td class="callDetails">'+lang.tag_call+"</td></tr>",s+='<tr id="CMDetails_3"><td><i class="fa fa-flag"></i></td><td class="callDetails">'+r+"</td></tr>",s+='<tr id="CMDetails_4"><td><i class="fa fa-quote-left"></i></td><td class="callDetails">'+lang.edit_comment+"</td></tr>"}"MSG"==i&&(s+='<tr id="CMDetails_5"><td><i class="fa fa-clipboard"></i></td><td class="callDetails">'+lang.copy_message+"</td></tr>",s+='<tr id="CMDetails_6"><td><i class="fa fa-quote-left"></i></td><td class="callDetails">'+lang.quote_message+"</td></tr>"),s+="</table></div>",$.jeegoopopup.open({html:s,width:"auto",height:"auto",left:o,top:l,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!1,resizable:!1,fadeIn:0}),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()})),$("#CMDetails_1").click((function(e){var t=null,i=JSON.parse(localDB.getItem(a+"-stream"));if(null==i&&null==i.DataCollection||$.each(i.DataCollection,(function(e,i){if("CDR"==i.ItemType&&i.CdrId==n)return t=i,!1})),null!=t){var o=[],l='<div id="windowCtrls"><img id="minimizeImg" src="images/1_minimize.svg" title="Restore" /><img id="maximizeImg" src="images/2_maximize.svg" title="Maximize" /><img id="closeImg" src="images/3_close.svg" title="Close" /></div>';l+='<div class="UiWindowField scroller">';var s=moment.utc(t.ItemDate.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat),r=t.CallAnswer?moment.utc(t.CallAnswer.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat):null,d=t.RingTime?t.RingTime:0,c=(moment.utc(t.CallEnd.replace(" UTC","")).local().format(DisplayDateFormat+" "+DisplayTimeFormat),""),u="";"inbound"==t.CallDirection?c=t.Src:"outbound"==t.CallDirection&&(u=t.Dst),l+="<div class=UiText><b>SIP CallID</b> : "+t.SessionId+"</div>",l+="<div class=UiText><b>"+lang.call_direction+"</b> : "+t.CallDirection+"</div>",l+="<div class=UiText><b>"+lang.call_date_and_time+"</b> : "+s+"</div>",l+="<div class=UiText><b>"+lang.ring_time+"</b> : "+formatDuration(d)+" ("+d+")</div>",l+="<div class=UiText><b>"+lang.talk_time+"</b> : "+formatDuration(t.Billsec)+" ("+t.Billsec+")</div>",l+="<div class=UiText><b>"+lang.call_duration+"</b> : "+formatDuration(t.TotalDuration)+" ("+t.TotalDuration+")</div>",l+="<div class=UiText><b>"+lang.video_call+"</b> : "+(t.WithVideo?lang.yes:lang.no)+"</div>",l+="<div class=UiText><b>"+lang.flagged+"</b> : "+(t.Flagged?'<i class="fa fa-flag FlagCall"></i> '+lang.yes:lang.no)+"</div>",l+="<hr>",l+='<h2 style="font-size: 16px">'+lang.call_tags+"</h2>",l+="<hr>",$.each(t.Tags,(function(e,t){l+="<span class=cdrTag>"+t.value+"</span>"})),l+='<h2 style="font-size: 16px">'+lang.call_notes+"</h2>",l+="<hr>",t.MessageData&&(l+='"'+t.MessageData+'"'),l+='<h2 style="font-size: 16px">'+lang.activity_timeline+"</h2>",l+="<hr>";var p=t.WithVideo?"("+lang.with_video+")":"",g="inbound"==t.CallDirection?lang.you_received_a_call_from+" "+c+" "+p:lang.you_made_a_call_to+" "+u+" "+p;if(o.push({Message:g,TimeStr:t.ItemDate}),r){var m="inbound"==t.CallDirection?lang.you_answered_after+" "+d+" "+lang.seconds_plural:lang.they_answered_after+" "+d+" "+lang.seconds_plural;o.push({Message:m,TimeStr:t.CallAnswer})}$.each(t.Transfers,(function(e,t){var i="Blind"==t.type?lang.you_started_a_blind_transfer_to+" "+t.to+". ":lang.you_started_an_attended_transfer_to+" "+t.to+". ";t.accept&&1==t.accept.complete?i+=lang.the_call_was_completed:""!=t.accept.disposition&&(i+=lang.the_call_was_not_completed+" ("+t.accept.disposition+")"),o.push({Message:i,TimeStr:t.transferTime})})),$.each(t.Mutes,(function(e,t){o.push({Message:"mute"==t.event?lang.you_put_the_call_on_mute:lang.you_took_the_call_off_mute,TimeStr:t.eventTime})})),$.each(t.Holds,(function(e,t){o.push({Message:"hold"==t.event?lang.you_put_the_call_on_hold:lang.you_took_the_call_off_hold,TimeStr:t.eventTime})})),$.each(t.ConfCalls,(function(e,t){var i=lang.you_started_a_conference_call_to+" "+t.to+". ";t.accept&&1==t.accept.complete?i+=lang.the_call_was_completed:""!=t.accept.disposition&&(i+=lang.the_call_was_not_completed+" ("+t.accept.disposition+")"),o.push({Message:i,TimeStr:t.startTime})})),$.each(t.Recordings,(function(e,t){var i=moment.utc(t.startTime.replace(" UTC","")).local(),n=moment.utc(t.stopTime.replace(" UTC","")).local(),a=moment.duration(n.diff(i)),l=lang.call_is_being_recorded;t.startTime!=t.stopTime&&(l+="("+formatShortDuration(a.asSeconds())+")"),o.push({Message:l,TimeStr:t.startTime})})),o.push({Message:"us"==t.Terminate?"You ended the call.":"They ended the call",TimeStr:t.CallEnd}),o.sort((function(e,t){var i=moment.utc(e.TimeStr.replace(" UTC","")),n=moment.utc(t.TimeStr.replace(" UTC",""));return i.isSameOrAfter(n,"second")?1:-1})),$.each(o,(function(e,t){var i="<table class=timelineMessage cellspacing=0 cellpadding=0><tr>";i+="<td class=timelineMessageArea>",i+='<div class=timelineMessageDate style="color: #333333"><i class="fa fa-circle timelineMessageDot"></i>'+moment.utc(t.TimeStr.replace(" UTC","")).local().format(DisplayTimeFormat)+"</div>",i+='<div class=timelineMessageText style="color: #000000">'+t.Message+"</div>",i+="</td>",l+=i+="</tr></table>"})),l+='<h2 style="font-size: 16px">'+lang.call_recordings+"</h2>",l+="<hr>";var f="";$.each(t.Recordings,(function(e,i){if(i.uID){var n=moment.utc(i.startTime.replace(" UTC","")).local(),a=moment.utc(i.stopTime.replace(" UTC","")).local(),o=moment.duration(a.diff(n));f+="<div>",t.WithVideo?f+='<div><video id="callrecording-video-'+i.uID+'" controls style="width: 100%"></div>':f+='<div><audio id="callrecording-audio-'+i.uID+'" controls style="width: 100%"></div>',f+="<div>"+lang.started+": "+n.format(DisplayTimeFormat)+' <i class="fa fa-long-arrow-right"></i> '+lang.stopped+": "+a.format(DisplayTimeFormat)+"</div>",f+="<div>"+lang.recording_duration+": "+formatShortDuration(o.asSeconds())+"</div>",f+='<div><a id="download-'+i.uID+'">'+lang.save_as+"</a> ("+lang.right_click_and_select_save_link_as+")</div>",f+="</div>"}})),l+=f,l+='<h2 style="font-size: 16px">'+lang.send_statistics+"</h2>",l+="<hr>",l+='<div style="position: relative; margin: auto; height: 160px; width: 100%;"><canvas id="cdr-AudioSendBitRate"></canvas></div>',l+='<div style="position: relative; margin: auto; height: 160px; width: 100%;"><canvas id="cdr-AudioSendPacketRate"></canvas></div>',l+='<h2 style="font-size: 16px">'+lang.receive_statistics+"</h2>",l+="<hr>",l+='<div style="position: relative; margin: auto; height: 160px; width: 100%;"><canvas id="cdr-AudioReceiveBitRate"></canvas></div>',l+='<div style="position: relative; margin: auto; height: 160px; width: 100%;"><canvas id="cdr-AudioReceivePacketRate"></canvas></div>',l+='<div style="position: relative; margin: auto; height: 160px; width: 100%;"><canvas id="cdr-AudioReceivePacketLoss"></canvas></div>',l+='<div style="position: relative; margin: auto; height: 160px; width: 100%;"><canvas id="cdr-AudioReceiveJitter"></canvas></div>',l+='<div style="position: relative; margin: auto; height: 160px; width: 100%;"><canvas id="cdr-AudioReceiveLevels"></canvas></div>',l+="<br><br></div>",$.jeegoopopup.close(),$.jeegoopopup.open({title:"Call Statistics",html:l,width:"640",height:"500",center:!0,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append('<button id="ok_button">'+lang.ok+"</button>"),DisplayQosData(t.SessionId);var v=$(window).width()-12,h=$(window).height()-88;v<656||h<500?($.jeegoopopup.width(v).height(h),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show()),$(window).resize((function(){v=$(window).width()-12,h=$(window).height()-88,$.jeegoopopup.center(),v<656||h<500?($.jeegoopopup.width(v).height(h),$.jeegoopopup.center(),$("#maximizeImg").hide(),$("#minimizeImg").hide()):($.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#minimizeImg").hide(),$("#maximizeImg").show())})),$("#minimizeImg").click((function(){$.jeegoopopup.width(640).height(500),$.jeegoopopup.center(),$("#maximizeImg").show(),$("#minimizeImg").hide()})),$("#maximizeImg").click((function(){$.jeegoopopup.width(v).height(h),$.jeegoopopup.center(),$("#minimizeImg").show(),$("#maximizeImg").hide()})),$("#closeImg").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#ok_button").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($.jeegoopopup.close(),$("#jg_popup_b").empty())})),$.each(t.Recordings,(function(e,i){var n=null;n=t.WithVideo?$("#callrecording-video-"+i.uID).get(0):$("#callrecording-audio-"+i.uID).get(0);var a=$("#download-"+i.uID),o=getAudioOutputID();void 0!==n.sinkId?n.setSinkId(o).then((function(){console.log("sinkId applied: "+o)})).catch((function(e){console.warn("Error using setSinkId: ",e)})):console.warn("setSinkId() is not possible using this browser.");var l=window.indexedDB.open("CallRecordings");l.onerror=function(e){console.error("IndexDB Request Error:",e)},l.onupgradeneeded=function(e){console.warn("Upgrade Required for IndexDB... probably because of first time use.")},l.onsuccess=function(e){console.log("IndexDB connected to CallRecordings");var o=e.target.result;if(0!=o.objectStoreNames.contains("Recordings")){var l=o.transaction(["Recordings"]).objectStore("Recordings").get(i.uID);l.onerror=function(e){console.error("IndexDB Get Error:",e)},l.onsuccess=function(e){var o=window.URL.createObjectURL(e.target.result.mediaBlob);n.src=o,t.WithVideo?a.prop("download","Video-Call-Recording-"+i.uID+".webm"):a.prop("download","Audio-Call-Recording-"+i.uID+".webm"),a.prop("href",o)}}else console.warn("IndexDB CallRecordings.Recordings does not exists")}}))}})),$("#CMDetails_2").click((function(e){$("#cdr-tags-"+n).show(),$.jeegoopopup.close()})),$("#CMDetails_3").click((function(e){var t;$("#cdr-flagged-"+n).is(":visible")?(console.log("Clearing Flag from: ",n),$("#cdr-flagged-"+n).hide(),null==(t=JSON.parse(localDB.getItem(a+"-stream")))&&null==t.DataCollection||($.each(t.DataCollection,(function(e,t){if("CDR"==t.ItemType&&t.CdrId==n)return t.Flagged=!1,!1})),localDB.setItem(a+"-stream",JSON.stringify(t)))):(console.log("Flag Call: ",n),$("#cdr-flagged-"+n).show(),null==(t=JSON.parse(localDB.getItem(a+"-stream")))&&null==t.DataCollection||($.each(t.DataCollection,(function(e,t){if("CDR"==t.ItemType&&t.CdrId==n)return t.Flagged=!0,!1})),localDB.setItem(a+"-stream",JSON.stringify(t))));$.jeegoopopup.close()})),$("#CMDetails_4").click((function(e){var t=$("#cdr-comment-"+n).text();$("#cdr-comment-"+n).empty();var i=$("<input maxlength=500 type=text>").appendTo("#cdr-comment-"+n);i.on("focus",(function(){$.jeegoopopup.close()})),i.on("blur",(function(){var e=$(this).val();SaveComment(n,a,e)})),i.keypress((function(e){if(window.setTimeout((function(){$.jeegoopopup.close()}),500),"13"==(e.keyCode?e.keyCode:e.which)){e.preventDefault();var t=$(this).val();SaveComment(n,a,t)}})),i.val(t),i.focus(),$.jeegoopopup.close()})),$("#CMDetails_5").click((function(t){var i=$("#msg-text-"+n).text();navigator.clipboard.writeText(i).then((function(){console.log("Text coppied to the clipboard:",i)})).catch((function(){console.error("Error writing to the clipboard:",e)})),$.jeegoopopup.close()})),$("#CMDetails_6").click((function(e){var t=$("#msg-text-"+n).text();t='"'+t+'"';var i=$("#contact-"+a+"-ChatMessage");console.log("Quote Message:",t),i.val(t+"\n"+i.val()),$.jeegoopopup.close()}))}function SaveComment(e,t,i){console.log("Setting Comment:",i),$("#cdr-comment-"+e).empty(),$("#cdr-comment-"+e).append(i);var n=JSON.parse(localDB.getItem(t+"-stream"));null==n&&null==n.DataCollection||($.each(n.DataCollection,(function(t,n){if("CDR"==n.ItemType&&n.CdrId==e)return n.MessageData=i,!1})),localDB.setItem(t+"-stream",JSON.stringify(n)))}function TagKeyPress(e,t,i,n){$.jeegoopopup.close();var a=e.keyCode?e.keyCode:e.which;if("13"==a||"44"==a){if(e.preventDefault(),""==$(t).val())return;console.log("Adding Tag:",$(t).val()),$("#cdr-tags-"+i+" li:last").before("<li onclick=\"TagClick(this, '"+i+"', '"+n+"')\">"+$(t).val()+"</li>"),$(t).val(""),UpdateTags(i,n)}}function TagClick(e,t,i){window.setTimeout((function(){$.jeegoopopup.close()}),500),console.log("Removing Tag:",$(e).text()),$(e).remove(),UpdateTags(t,i)}function UpdateTags(e,t){var i=JSON.parse(localDB.getItem(t+"-stream"));null==i&&null==i.DataCollection||($.each(i.DataCollection,(function(t,i){if("CDR"==i.ItemType&&i.CdrId==e)return i.Tags=[],$("#cdr-tags-"+e).children("li").each((function(){"tagText"!=$(this).prop("class")&&i.Tags.push({value:$(this).text()})})),!1})),localDB.setItem(t+"-stream",JSON.stringify(i)))}function TagFocus(e){$.jeegoopopup.close()}function SendFile(e){$("#selectedFile").val(""),$("#upFile").empty();var t='<form id="sendFileFormChat" enctype="multipart/form-data">';t+='<input type="hidden" name="MAX_FILE_SIZE" value="786432000" />',t+='<input type="hidden" name="sipUser" value="'+FindBuddyByIdentity(e).ExtNo+'" />',t+='<input type="hidden" name="s_ajax_call" value="'+validateSToken+'" />',t+='<label for="selectedFile" class="customBrowseButton">Select File</label>',t+='<span id="upFile"></span>',t+='<input type="file" id="selectedFile" name="uploadedFile" />',t+='<input type="submit" id="submitFileChat" value="Send File" style="visibility:hidden;"/>',t+="</form>",$("#sendFileFormChat").is(":visible")?($("#sendFileFormChat").remove(),sendFileCheck=0):(sendFileCheck=1,$("#contact-"+e+"-ChatMessage").before(t),$("#sendFileFormChat").css("display","block"),$("#selectedFile").bind("change",(function(){upFileName=$(this).val().split("\\").pop(),/^[a-zA-Z0-9\-\_\.]+$/.test(upFileName)?$("#upFile").html(upFileName):($("#sendFileFormChat").remove(),sendFileCheck=0,alert("The name of the uploaded file is not valid!"))})))}function ShowEmojiBar(e){var t=$("#contact-"+e+"-emoji-menu"),i=$("#contact-"+e+"-ChatMessage");t.is(":visible")?t.hide():t.show();var n=$("<div>");n.prop("class","emojiButton");$.each(["😀","😁","😂","😃","😄","😅","😆","😊","😦","😉","😊","😋","😌","😍","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😛","😜","😝","😞","😟","😠","😡","😢","😣","😤","😥","😦","😧","😨","😩","😪","😫","😬","😭","😮","😯","😰","😱","😲","😳","😴","😵","😶","😷","🙁","🙂","🙃","🙄","🤐","🤑","🤒","🤓","🤔","🤕","🤠","🤡","🤢","🤣","🤤","🤥","🤧","🤨","🤩","🤪","🤫","🤬","🥺","🤭","🤯","🧐"],(function(a,o){var l=$("<button>");l.html(o),l.on("click",(function(){var n=i.prop("selectionStart"),a=i.val();i.val(a.substring(0,n)+" "+$(this).html()+a.substring(n,a.length)+" "),t.hide(),i.focus(),updateScroll(e)})),n.append(l)})),$(".chatMessage,.chatHistory").on("click",(function(){t.hide()})),t.empty(),t.append(n),updateScroll(e)}function ShowMyProfileMenu(e){e.offsetWidth;var t=e.offsetHeight+56;if("superadmin"==getDbItem("userrole",""))var i="(superadmin)";else i="";var n="<font style='color:#000000;cursor:auto;'>"+userName+" "+i+"</font>",a=AutoAnswerEnabled?"<i class='fa fa-check' style='float:right;'></i>":"",o=DoNotDisturbEnabled?"<i class='fa fa-check' style='float:right;'></i>":"",l=CallWaitingEnabled?"<i class='fa fa-check' style='float:right;'></i>":"",s="<div id=userMenu>";s+='<table id=userMenuTable cellspacing=10 cellpadding=0 style="margin-left:auto; margin-right: auto">',s+='<tr id=userMenu_1><td><i class="fa fa-phone"></i> '+lang.auto_answer+'<span id="autoAnswerTick">'+a+"</span></td></tr>",s+='<tr id=userMenu_2><td><i class="fa fa-ban"></i> '+lang.do_not_disturb+'<span id="doNotDisturbTick">'+o+"</span></td></tr>",s+='<tr id=userMenu_3><td><i class="fa fa-volume-control-phone"></i> '+lang.call_waiting+'<span id="callWaitingTick">'+l+"</span></td></tr>",s+='<tr id=userMenu_4><td><i class="fa fa-refresh"></i> '+lang.refresh_registration+"</td></tr>",s+='<tr id=userMenu_5><td><i class="fa fa-user-plus"></i> '+lang.add_contact+"</td></tr>",s+="<tr id=userMenu_6><td><font style='color:#000000;cursor:auto;'>"+lang.logged_in_as+"</font></td></tr>",s+="<tr id=userMenu_7><td><span style='width:20px;'></span>"+n+"</td></tr>",s+='<tr id=userMenu_8><td><i class="fa fa-power-off"></i> '+lang.log_out+"</td></tr>",s+="</table>",s+="</div>",$.jeegoopopup.open({html:s,width:"auto",height:"auto",left:"56",top:t,scrolling:"no",skinClass:"jg_popup_basic",innerClass:"userMenuInner",contentClass:"userMenuContent",overlay:!0,opacity:0,draggable:!1,resizable:!1,fadeIn:0}),$(window).resize((function(){$.jeegoopopup.width("auto").height("auto").left("56").top(t)})),$("#userMenu_1").click((function(){ToggleAutoAnswer(),AutoAnswerEnabled?$("#autoAnswerTick").append("<i class='fa fa-check' style='float:right;'></i>"):$("#autoAnswerTick").empty()})),$("#userMenu_2").click((function(){ToggleDoNoDisturb(),DoNotDisturbEnabled?$("#doNotDisturbTick").append("<i class='fa fa-check' style='float:right;'></i>"):$("#doNotDisturbTick").empty()})),$("#userMenu_3").click((function(){ToggleCallWaiting(),CallWaitingEnabled?$("#callWaitingTick").append("<i class='fa fa-check' style='float:right;'></i>"):$("#callWaitingTick").empty()})),$("#userMenu_4").click((function(){RefreshRegistration()})),$("#userMenu_5").click((function(){AddSomeoneWindow()})),$("#userMenu_8").click((function(){SignOut()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}function ShowLaunchVidConfMenu(e){var t=e.offsetWidth+121,i=0,n=e.offsetHeight+117;$(window).width()<=915&&(t=event.pageX+e.offsetWidth-113,i=0,n=event.pageY+e.offsetHeight-11);var a="<div id=videoConfMenu>";a+='<table id=lauchVConfTable cellspacing=0 cellpadding=0 style="margin: 0px">',a+='<tr id=launchVConfMenu_1><td><i class="fa fa-users"></i> '+lang.launch_video_conference+"</td></tr>",a+="</table>",a+="</div>",$.jeegoopopup.open({html:a,width:"228",height:"22",left:t,right:i,top:n,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!1,resizable:!1,fadeIn:0}),$(window).resize((function(){$.jeegoopopup.width("228").height("22").left(t).top(n)})),$(window).width()<=915?$.jeegoopopup.right(6):$.jeegoopopup.width("228").height("22").left(t).top(n),$("#launchVConfMenu_1").click((function(){LaunchVideoConference(),$.jeegoopopup.close()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}function ShowAccountSettingsMenu(e){$.jeegoopopup.close();var t=e.offsetWidth+212,i=0,n=e.offsetHeight+117;$(window).width()<=915&&(t=event.pageX-32,i=0,n=event.pageY+11);var a="<div id=settingsCMenu>";a+='<table id=lauchSetConfTable cellspacing=0 cellpadding=0 style="margin: 0px">',a+='<tr id=settingsCMenu_1><td><i class="fa fa-wrench"></i> '+lang.account_settings+"</td></tr>",a+="</table>",a+="</div>",$.jeegoopopup.open({html:a,width:"94",height:"22",left:t,right:i,top:n,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!1,resizable:!1,fadeIn:0}),$(window).resize((function(){$.jeegoopopup.width("94").height("22").left(t).top(n)})),$(window).width()<=915?$.jeegoopopup.right(6):$.jeegoopopup.width("94").height("22").left(t).top(n),$("#settingsCMenu_1").click((function(){ConfigureExtensionWindow()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}function RefreshRegistration(){Unregister(),console.log("Unregister complete..."),window.setTimeout((function(){console.log("Starting registration..."),Register()}),1e3)}function SignOut(){if(1==getDbItem("useRoundcube","")&&1==RCLoginCheck){$("#roundcubeFrame").remove(),$("#rightContent").show(),$(".streamSelected").each((function(){$(this).css("display","none")})),$("#rightContent").append('<iframe id="rcLogoutFrame" name="logoutFrame"></iframe>');var e='<form id="rcloForm" method="POST" action="'+("https://"+getDbItem("rcDomain","")+"/")+'" target="logoutFrame">';e+='<input type="hidden" name="_action" value="logout" />',e+='<input type="hidden" name="_task" value="logout" />',e+='<input type="hidden" name="_autologout" value="1" />',e+='<input id="submitloButton" type="submit" value="Logout" />',e+="</form>",$("#rcLogoutFrame").append(e),$("#submitloButton").click()}removeTextChatUploads(getDbItem("SipUsername","")),setTimeout((function(){var e=getDbItem("externalUserConfElem","");void 0!==e&&null!=e&&0!=e?checkExternalLinks():(Unregister(),console.log("Signing Out ..."),localStorage.clear(),null!=winVideoConf&&winVideoConf.close(),window.open("https://"+window.location.host+"/logout.php","_self"))}),100)}function ToggleAutoAnswer(){if("disabled"==AutoAnswerPolicy)return AutoAnswerEnabled=!1,void console.warn("Policy AutoAnswer: Disabled");AutoAnswerEnabled=1!=AutoAnswerEnabled,"enabled"==AutoAnswerPolicy&&(AutoAnswerEnabled=!0),localDB.setItem("AutoAnswerEnabled",1==AutoAnswerEnabled?"1":"0"),console.log("AutoAnswer:",AutoAnswerEnabled)}function ToggleDoNoDisturb(){if("disabled"==DoNotDisturbPolicy)return DoNotDisturbEnabled=!1,void console.warn("Policy DoNotDisturb: Disabled");DoNotDisturbEnabled=1!=DoNotDisturbEnabled,"enabled"==DoNotDisturbPolicy&&(DoNotDisturbEnabled=!0),localDB.setItem("DoNotDisturbEnabled",1==DoNotDisturbEnabled?"1":"0"),$("#dereglink").attr("class",1==DoNotDisturbEnabled?"dotDoNotDisturb":"dotOnline"),console.log("DoNotDisturb",DoNotDisturbEnabled)}function ToggleCallWaiting(){if("disabled"==CallWaitingPolicy)return CallWaitingEnabled=!1,void console.warn("Policy CallWaiting: Disabled");CallWaitingEnabled=1!=CallWaitingEnabled,"enabled"==CallWaitingPolicy&&(CallWaitingPolicy=!0),localDB.setItem("CallWaitingEnabled",1==CallWaitingEnabled?"1":"0"),console.log("CallWaiting",CallWaitingEnabled)}function ToggleRecordAllCalls(){if("disabled"==CallRecordingPolicy)return RecordAllCalls=!1,void console.warn("Policy CallRecording: Disabled");RecordAllCalls=1!=RecordAllCalls,"enabled"==CallRecordingPolicy&&(RecordAllCalls=!0),localDB.setItem("RecordAllCalls",1==RecordAllCalls?"1":"0"),console.log("RecordAllCalls",RecordAllCalls)}function ShowBuddyProfileMenu(e,t,i){$.jeegoopopup.close(),leftPos=event.pageX-60,topPos=event.pageY+45;var n=FindBuddyByIdentity(e);if("extension"==i){var a='<div style="width:200px; cursor:pointer" onclick="EditBuddyWindow(\''+e+"')\">";a+='<div class="buddyProfilePic" style="background-image:url(\''+getPicture(e,"extension")+"')\"></div>",a+='<div id=ProfileInfo style="text-align:center"><i class="fa fa-spinner fa-spin"></i></div>',a+="</div>",$.jeegoopopup.open({html:a,width:"200",height:"auto",left:leftPos,top:topPos,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"showContactDetails",overlay:!0,opacity:0,draggable:!0,resizable:!1,fadeIn:0}),$("#ProfileInfo").html(""),$("#ProfileInfo").append('<div class=ProfileTextLarge style="margin-top:15px">'+n.CallerIDName+"</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.Desc+"</div>"),$("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.extension_number+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.ExtNo+" </div>"),n.Email&&"null"!=n.Email&&"undefined"!=n.Email&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.email+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.Email+" </div>")),n.MobileNumber&&"null"!=n.MobileNumber&&"undefined"!=n.MobileNumber&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.mobile+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.MobileNumber+" </div>")),n.ContactNumber1&&"null"!=n.ContactNumber1&&"undefined"!=n.ContactNumber1&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.alternative_contact+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.ContactNumber1+" </div>")),n.ContactNumber2&&"null"!=n.ContactNumber2&&"undefined"!=n.ContactNumber2&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.alternative_contact+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.ContactNumber2+" </div>"))}else if("contact"==i){a='<div style="width:200px; cursor:pointer" onclick="EditBuddyWindow(\''+e+"')\">";a+='<div class="buddyProfilePic" style="background-image:url(\''+getPicture(e,"contact")+"')\"></div>",a+='<div id=ProfileInfo style="text-align:center"><i class="fa fa-spinner fa-spin"></i></div>',a+="</div>",$.jeegoopopup.open({html:a,width:"200",height:"auto",left:leftPos,top:topPos,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"showContactDetails",overlay:!0,opacity:0,draggable:!0,resizable:!1,fadeIn:0}),$("#ProfileInfo").html(""),$("#ProfileInfo").append('<div class=ProfileTextLarge style="margin-top:15px">'+n.CallerIDName+"</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.Desc+"</div>"),n.Email&&"null"!=n.Email&&"undefined"!=n.Email&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.email+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.Email+" </div>")),n.MobileNumber&&"null"!=n.MobileNumber&&"undefined"!=n.MobileNumber&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.mobile+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.MobileNumber+" </div>")),n.ContactNumber1&&"null"!=n.ContactNumber1&&"undefined"!=n.ContactNumber1&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.alternative_contact+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.ContactNumber1+" </div>")),n.ContactNumber2&&"null"!=n.ContactNumber2&&"undefined"!=n.ContactNumber2&&($("#ProfileInfo").append('<div class=ProfileTextSmall style="margin-top:15px">'+lang.alternative_contact+":</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.ContactNumber2+" </div>"))}else if("group"==i){a='<div style="width:200px; cursor:pointer" onclick="EditBuddyWindow(\''+e+"')\">";a+='<div class="buddyProfilePic" style="background-image:url(\''+getPicture(e,"group")+"')\"></div>",a+='<div id=ProfileInfo style="text-align:center"><i class="fa fa-spinner fa-spin"></i></div>',a+="</div>",$.jeegoopopup.open({html:a,width:"200",height:"auto",left:leftPos,top:topPos,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"showContactDetails",overlay:!0,opacity:0,draggable:!0,resizable:!1,fadeIn:0}),$("#ProfileInfo").html(""),$("#ProfileInfo").append('<div class=ProfileTextLarge style="margin-top:15px">'+n.CallerIDName+"</div>"),$("#ProfileInfo").append("<div class=ProfileTextMedium>"+n.Desc+"</div>")}$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}function ChangeSettings(e,t){var i=event.pageX-138,n=event.pageY+28;$(window).height()-event.pageY<300&&(n=event.pageY-170);var a=FindLineByNumber(e);if(null!=a&&null!=a.SipSession){var o=a.SipSession;$.jeegoopopup.open({html:'<div id=DeviceSelector style="width:250px"></div>',width:"auto",height:"auto",left:i,top:n,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"callSettingsContent",overlay:!0,opacity:0,draggable:!0,resizable:!1,fadeIn:0});var l=$("<select/>");l.prop("id","audioSrcSelect"),l.css("width","100%");var s=$("<select/>");s.prop("id","videoSrcSelect"),s.css("width","100%");var r=$("<select/>");r.prop("id","audioOutputSelect"),r.css("width","100%");var d=$("<select/>");if(d.prop("id","ringerSelect"),d.css("width","100%"),l.change((function(){console.log("Call to change Microphone: ",this.value);var t=!1;o.data.mediaRecorder&&"recording"==o.data.mediaRecorder.state&&(StopRecording(e,!0),t=!0),a.LocalSoundMeter&&a.LocalSoundMeter.stop(),o.data.AudioSourceDevice=this.value;var i={audio:{deviceId:"default"!=this.value?{exact:this.value}:"default"},video:!1};navigator.mediaDevices.getUserMedia(i).then((function(i){var n=i.getAudioTracks()[0];o.sessionDescriptionHandler.peerConnection.getSenders().forEach((function(i){i.track&&"audio"==i.track.kind&&(console.log("Switching Audio Track : "+i.track.label+" to "+n.label),i.track.stop(),i.replaceTrack(n).then((function(){t&&StartRecording(e),a.LocalSoundMeter=StartLocalAudioMediaMonitoring(e,o)})).catch((function(e){console.error("Error replacing track: ",e)})))}))})).catch((function(e){console.error("Error on getUserMedia")}))})),r.change((function(){console.log("Call to change Speaker: ",this.value),o.data.AudioOutputDevice=this.value;var t=this.value;console.log("Attempting to set Audio Output SinkID for line "+e+" ["+t+"]");var i=$("#line-"+e+"-remoteAudio").get(0);i&&(void 0!==i.sinkId?i.setSinkId(t).then((function(){console.log("sinkId applied: "+t)})).catch((function(e){console.warn("Error using setSinkId: ",e)})):console.warn("setSinkId() is not possible using this browser."))})),s.change((function(){console.log("Call to change WebCam"),switchVideoSource(e,this.value)})),navigator.mediaDevices){for(var c=0;c<AudioinputDevices.length;++c){var u=(p=AudioinputDevices[c]).deviceId;(g=p.label?p.label:"").indexOf("(")>0&&(g=g.substring(0,g.indexOf("("))),(m=$("<option/>")).prop("value",u),m.text(""!=g?g:"Microphone"),o.data.AudioSourceDevice==u&&m.prop("selected",!0),l.append(m)}for(c=0;c<VideoinputDevices.length;++c){u=(p=VideoinputDevices[c]).deviceId;(g=p.label?p.label:"").indexOf("(")>0&&(g=g.substring(0,g.indexOf("("))),(m=$("<option/>")).prop("value",u),m.text(""!=g?g:"Webcam"),o.data.VideoSourceDevice==u&&m.prop("selected",!0),s.append(m)}if(HasSpeakerDevice)for(c=0;c<SpeakerDevices.length;++c){var p,g,m;u=(p=SpeakerDevices[c]).deviceId;(g=p.label?p.label:"").indexOf("(")>0&&(g=g.substring(0,g.indexOf("("))),(m=$("<option/>")).prop("value",u),m.text(""!=g?g:"Speaker"),o.data.AudioOutputDevice==u&&m.prop("selected",!0),r.append(m)}$("#DeviceSelector").append("<div class=callSettingsDvs>"+lang.microphone+": </div>"),$("#DeviceSelector").append(l),HasSpeakerDevice&&($("#DeviceSelector").append("<div class=callSettingsDvs>"+lang.speaker+": </div>"),$("#DeviceSelector").append(r)),1==o.data.withvideo&&($("#DeviceSelector").append("<div class=callSettingsDvs>"+lang.camera+": </div>"),$("#DeviceSelector").append(s)),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}else console.warn("navigator.mediaDevices not possible.")}}function PresentCamera(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;$("#line-"+e+"-src-camera").prop("disabled",!0),$("#line-"+e+"-src-canvas").prop("disabled",!1),$("#line-"+e+"-src-desktop").prop("disabled",!1),$("#line-"+e+"-src-video").prop("disabled",!1),$("#line-"+e+"-src-blank").prop("disabled",!1),$("#line-"+e+"-scratchpad-container").hide(),RemoveScratchpad(e),$("#line-"+e+"-sharevideo").hide(),$("#line-"+e+"-sharevideo").get(0).pause(),$("#line-"+e+"-sharevideo").get(0).removeAttribute("src"),$("#line-"+e+"-sharevideo").get(0).load(),window.clearInterval(i.data.videoResampleInterval),$("#line-"+e+"-localVideo").show(),$("#line-"+e+"-remoteVideo").appendTo("#line-"+e+"-stage-container"),switchVideoSource(e,i.data.VideoSourceDevice)}else console.warn("Line or Session is Null.")}function PresentScreen(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;$("#line-"+e+"-src-camera").prop("disabled",!1),$("#line-"+e+"-src-canvas").prop("disabled",!1),$("#line-"+e+"-src-desktop").prop("disabled",!0),$("#line-"+e+"-src-video").prop("disabled",!1),$("#line-"+e+"-src-blank").prop("disabled",!1),$("#line-"+e+"-scratchpad-container").hide(),RemoveScratchpad(e),$("#line-"+e+"-sharevideo").hide(),$("#line-"+e+"-sharevideo").get(0).pause(),$("#line-"+e+"-sharevideo").get(0).removeAttribute("src"),$("#line-"+e+"-sharevideo").get(0).load(),window.clearInterval(i.data.videoResampleInterval),$("#line-"+e+"-localVideo").hide(),$("#line-"+e+"-remoteVideo").appendTo("#line-"+e+"-stage-container"),ShareScreen(e)}else console.warn("Line or Session is Null.")}function PresentScratchpad(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;$("#line-"+e+"-src-camera").prop("disabled",!1),$("#line-"+e+"-src-canvas").prop("disabled",!0),$("#line-"+e+"-src-desktop").prop("disabled",!1),$("#line-"+e+"-src-video").prop("disabled",!1),$("#line-"+e+"-src-blank").prop("disabled",!1),$("#line-"+e+"-scratchpad-container").hide(),RemoveScratchpad(e),$("#line-"+e+"-sharevideo").hide(),$("#line-"+e+"-sharevideo").get(0).pause(),$("#line-"+e+"-sharevideo").get(0).removeAttribute("src"),$("#line-"+e+"-sharevideo").get(0).load(),window.clearInterval(i.data.videoResampleInterval),$("#line-"+e+"-localVideo").hide(),$("#line-"+e+"-remoteVideo").appendTo("#line-"+e+"-preview-container"),SendCanvas(e)}else console.warn("Line or Session is Null.")}function PresentVideo(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){t.SipSession;$.jeegoopopup.close();'<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>','<label for=SelectVideoToSend class=customBrowseButton style="display: block; margin: 26px auto;">Select File</label>','<div class="UiWindowField"><input type=file accept="video/*" id=SelectVideoToSend></div>',"</div>",$.jeegoopopup.open({html:'<div><div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div><label for=SelectVideoToSend class=customBrowseButton style="display: block; margin: 26px auto;">Select File</label><div class="UiWindowField"><input type=file accept="video/*" id=SelectVideoToSend></div></div>',width:"180",height:"80",center:!0,scrolling:"no",skinClass:"jg_popup_basic",overlay:!0,opacity:0,draggable:!0,resizable:!1,fadeIn:0}),$("#SelectVideoToSend").on("change",(function(t){var i=t.target;i.files.length>=1?($.jeegoopopup.close(),SendVideo(e,URL.createObjectURL(i.files[0]))):console.warn("Please Select a file to present.")})),$("#closeImg").click((function(){$.jeegoopopup.close()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close()})),$(window).on("keydown",(function(e){"Escape"==e.key&&$.jeegoopopup.close()}))}else console.warn("Line or Session is Null.")}function PresentBlank(e){var t=FindLineByNumber(e);if(null!=t&&null!=t.SipSession){var i=t.SipSession;$("#line-"+e+"-src-camera").prop("disabled",!1),$("#line-"+e+"-src-canvas").prop("disabled",!1),$("#line-"+e+"-src-desktop").prop("disabled",!1),$("#line-"+e+"-src-video").prop("disabled",!1),$("#line-"+e+"-src-blank").prop("disabled",!0),$("#line-"+e+"-scratchpad-container").hide(),RemoveScratchpad(e),$("#line-"+e+"-sharevideo").hide(),$("#line-"+e+"-sharevideo").get(0).pause(),$("#line-"+e+"-sharevideo").get(0).removeAttribute("src"),$("#line-"+e+"-sharevideo").get(0).load(),window.clearInterval(i.data.videoResampleInterval),$("#line-"+e+"-localVideo").hide(),$("#line-"+e+"-remoteVideo").appendTo("#line-"+e+"-stage-container"),DisableVideoStream(e)}else console.warn("Line or Session is Null.")}function RemoveScratchpad(e){var t=GetCanvas("line-"+e+"-scratchpad");null!=t&&(window.clearInterval(t.redrawIntrtval),RemoveCanvas("line-"+e+"-scratchpad"),$("#line-"+e+"-scratchpad-container").empty(),t=null)}function ShowCallStats(e,t){console.log("Show Call Stats"),$("#line-"+e+"-AudioStats").show(300)}function HideCallStats(e,t){console.log("Hide Call Stats"),$("#line-"+e+"-AudioStats").hide(300)}function chatOnbeforepaste(e,t,i){console.log("Handle paste, checking for Images...");for(var n=(e.clipboardData||e.originalEvent.clipboardData).items,a=!1,o=0;o<n.length;o++)if(0!==n[o].type.indexOf("image"));else{console.log("Image found! Opening image editor...");var l=n[o].getAsFile(),s=new FileReader;s.onload=function(e){console.log("Image loaded... setting placeholder...");var t=new Image;t.onload=function(){console.log("Placeholder loaded... CreateImageEditor..."),CreateImageEditor(i,t)},t.src=e.target.result},s.readAsDataURL(l),a=!0}a&&e.preventDefault()}function chatOnkeydown(e,t,i){if("13"==(e.keyCode?e.keyCode:e.which)&&e.ctrlKey)return SendChatMessage(i),!1}function ReformatMessage(e){var t=e;return t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace(/</gi,"<")).replace(/>/gi,">")).replace(/\n/gi,"<br>")).replace(/(:\)|:\-\)|:o\))/g,String.fromCodePoint(128578))).replace(/(:\(|:\-\(|:o\()/g,String.fromCodePoint(128577))).replace(/(;\)|;\-\)|;o\))/g,String.fromCodePoint(128521))).replace(/(:'\(|:'\-\()/g,String.fromCodePoint(128554))).replace(/(:'\(|:'\-\()/g,String.fromCodePoint(128514))).replace(/(:\$)/g,String.fromCodePoint(128563))).replace(/(>:\()/g,String.fromCodePoint(128547))).replace(/(:\×)/g,String.fromCodePoint(128536))).replace(/(:\O|:\‑O)/g,String.fromCodePoint(128562))).replace(/(:P|:\-P|:p|:\-p)/g,String.fromCodePoint(128539))).replace(/(;P|;\-P|;p|;\-p)/g,String.fromCodePoint(128540))).replace(/(:D|:\-D)/g,String.fromCodePoint(128525))).replace(/(\(like\))/g,String.fromCodePoint(128077))).replace(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/gi,(function(e){var t=e.length>50?e.substring(0,47)+"...":e;return'<A target=_blank class=previewHyperlink href="'+e+'">'+t+"</A>"}))}function getPicture(e,t){if("profilePicture"==e)return null==(i=localDB.getItem("profilePicture"))?hostingPrefex+"images/default.png":i;t=t||"extension";var i,n=FindBuddyByIdentity(e);return""!=n.imageObjectURL?n.imageObjectURL:null==(i=localDB.getItem("img-"+e+"-"+t))?hostingPrefex+"images/default.png":(n.imageObjectURL=URL.createObjectURL(base64toBlob(i,"image/png")),n.imageObjectURL)}function CreateImageEditor(e,t){console.log("Setting Up ImageEditor..."),$("#contact-"+e+"-imagePastePreview").is(":visible")?(console.log("Resetting ImageEditor..."),$("#contact-"+e+"-imagePastePreview").empty(),RemoveCanvas("contact-"+e+"-imageCanvas")):$("#contact-"+e+"-imagePastePreview").show();var i=$("<div/>");i.css("margin-bottom","5px"),i.append('<button class="toolBarButtons" title="Select" onclick="ImageEditor_Select(\''+e+'\')"><i class="fa fa-mouse-pointer"></i></button>'),i.append(" | "),i.append('<button class="toolBarButtons" title="Draw" onclick="ImageEditor_FreedrawPen(\''+e+'\')"><i class="fa fa-pencil"></i></button>'),i.append('<button class="toolBarButtons" title="Paint" onclick="ImageEditor_FreedrawPaint(\''+e+'\')"><i class="fa fa-paint-brush"></i></button>'),i.append(" | "),i.append('<button class="toolBarButtons" title="Select Line Color" onclick="ImageEditor_SetectLineColor(\''+e+'\')"><i class="fa fa-pencil-square-o" style="color:rgb(255, 0, 0)"></i></button>'),i.append('<button class="toolBarButtons" title="Select Fill Color" onclick="ImageEditor_SetectFillColor(\''+e+'\')"><i class="fa fa-pencil-square" style="color:rgb(255, 0, 0)"></i></button>'),i.append(" | "),i.append('<button class="toolBarButtons" title="Add Circle" onclick="ImageEditor_AddCircle(\''+e+'\')"><i class="fa fa-circle"></i></button>'),i.append('<button class="toolBarButtons" title="Add Rectangle" onclick="ImageEditor_AddRectangle(\''+e+'\')"><i class="fa fa-stop"></i></button>'),i.append('<button class="toolBarButtons" title="Add Triangle" onclick="ImageEditor_AddTriangle(\''+e+'\')"><i class="fa fa-play"></i></button>'),i.append('<button class="toolBarButtons" title="Add Emoji" onclick="ImageEditor_SetectEmoji(\''+e+'\')"><i class="fa fa-smile-o"></i></button>'),i.append('<button class="toolBarButtons" title="Add Text" onclick="ImageEditor_AddText(\''+e+'\')"><i class="fa fa-font"></i></button>'),i.append('<button class="toolBarButtons" title="Delete Selected Items" onclick="ImageEditor_Clear(\''+e+'\')"><i class="fa fa-times"></i></button>'),i.append('<button class="toolBarButtons" title="Clear All" onclick="ImageEditor_ClearAll(\''+e+'\')"><i class="fa fa-trash"></i></button>'),i.append(" | "),i.append('<button class="toolBarButtons" title="Pan" onclick="ImageEditor_Pan(\''+e+'\')"><i class="fa fa-hand-paper-o"></i></button>'),i.append('<button class="toolBarButtons" title="Zoom In" onclick="ImageEditor_ZoomIn(\''+e+'\')"><i class="fa fa-search-plus"></i></button>'),i.append('<button class="toolBarButtons" title="Zoom Out" onclick="ImageEditor_ZoomOut(\''+e+'\')"><i class="fa fa-search-minus"></i></button>'),i.append('<button class="toolBarButtons" title="Reset Pan & Zoom" onclick="ImageEditor_ResetZoom(\''+e+'\')"><i class="fa fa-search" aria-hidden="true"></i></button>'),i.append(" | "),i.append('<button class="toolBarButtons" title="Cancel" onclick="ImageEditor_Cancel(\''+e+'\')"><i class="fa fa-times-circle"></i></button>'),i.append('<button class="toolBarButtons" title="Send" onclick="ImageEditor_Send(\''+e+'\')"><i class="fa fa-paper-plane"></i></button>'),$("#contact-"+e+"-imagePastePreview").append(i);var n=$("<canvas/>");n.prop("id","contact-"+e+"-imageCanvas"),n.css("border","1px solid #CCCCCC"),$("#contact-"+e+"-imagePastePreview").append(n),console.log("Canvas for ImageEditor created...");var a=t.width,o=t.height,l=$("#contact-"+e+"-imagePastePreview").width()-2;$("#contact-"+e+"-imageCanvas").prop("width",l),$("#contact-"+e+"-imageCanvas").prop("height",480);var s=1,r=1,d=1;a>l||o>480?(a>l&&(r=l/a),o>480&&(d=480/o,console.log("Scale to fit height: "+d)),s=Math.min(r,d),console.log("Scale down to fit: "+s),a*=s,o*=s,console.log("resizing canvas to fit new image size..."),$("#contact-"+e+"-imageCanvas").prop("width",a),$("#contact-"+e+"-imageCanvas").prop("height",o)):(console.log("Image is able to fit, resizing canvas..."),$("#contact-"+e+"-imageCanvas").prop("width",a),$("#contact-"+e+"-imageCanvas").prop("height",o)),console.log("Creating fabric API...");var c=new fabric.Canvas("contact-"+e+"-imageCanvas");c.id="contact-"+e+"-imageCanvas",c.ToolSelected="None",c.PenColour="rgb(255, 0, 0)",c.PenWidth=2,c.PaintColour="rgba(227, 230, 3, 0.6)",c.PaintWidth=10,c.FillColour="rgb(255, 0, 0)",c.isDrawingMode=!1,c.selectionColor="rgba(112,179,233,0.25)",c.selectionBorderColor="rgba(112,179,233, 0.8)",c.selectionLineWidth=1,c.setZoom(s),c.on("mouse:down",(function(e){var t=e.e;"Pan"==this.ToolSelected&&(this.isDragging=!0,this.selection=!1,this.lastPosX=t.clientX,this.lastPosY=t.clientY),null!=e.target&&(!0===t.altKey&&(e.target.lockMovementX=!0),!0===t.shiftKey&&(e.target.lockMovementY=!0),e.target.set({transparentCorners:!1,borderColor:"rgba(112,179,233, 0.4)",cornerColor:"rgba(112,179,233, 0.8)",cornerSize:6}))})),c.on("mouse:move",(function(e){if(this.isDragging){var t=e.e;this.viewportTransform[4]+=t.clientX-this.lastPosX,this.viewportTransform[5]+=t.clientY-this.lastPosY,this.requestRenderAll(),this.lastPosX=t.clientX,this.lastPosY=t.clientY}})),c.on("mouse:up",(function(e){this.isDragging=!1,this.selection=!0,null!=e.target&&(e.target.lockMovementX=!1,e.target.lockMovementY=!1)})),c.on("mouse:wheel",(function(e){var t=e.e.deltaY,i=(c.getPointer(e.e),c.getZoom());(i+=t/200)>10&&(i=10),i<.1&&(i=.1),c.zoomToPoint({x:e.e.offsetX,y:e.e.offsetY},i),e.e.preventDefault(),e.e.stopPropagation()})),c.backgroundImage=new fabric.Image(t),CanvasCollection.push(c),$("#contact-"+e+"-imagePastePreview").keydown((function(t){var i=(t=t||window.event).keyCode;console.log("Key press on Image Editor ("+e+"): "+i),46==i&&ImageEditor_Clear(e)})),console.log("ImageEditor: "+c.id+" created"),ImageEditor_FreedrawPen(e)}function GetCanvas(e){for(var t=0;t<CanvasCollection.length;t++)try{if(CanvasCollection[t].id==e)return CanvasCollection[t]}catch(e){console.warn("CanvasCollection.id not available")}return null}function RemoveCanvas(e){for(var t=0;t<CanvasCollection.length;t++)try{if(CanvasCollection[t].id==e){console.log("Found Old Canvas, Disposing..."),CanvasCollection[t].clear(),CanvasCollection[t].dispose(),CanvasCollection[t].id="--deleted--",console.log("CanvasCollection.splice("+t+", 1)"),CanvasCollection.splice(t,1);break}}catch(e){}console.log("There are "+CanvasCollection.length+" canvas now.")}var ImageEditor_Select=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");return null!=t&&(t.ToolSelected="none",t.isDrawingMode=!1,!0)},ImageEditor_FreedrawPen=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");return null!=t&&(t.freeDrawingBrush.color=t.PenColour,t.freeDrawingBrush.width=t.PenWidth,t.ToolSelected="Draw",t.isDrawingMode=!0,console.log(t),!0)},ImageEditor_FreedrawPaint=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");return null!=t&&(t.freeDrawingBrush.color=t.PaintColour,t.freeDrawingBrush.width=t.PaintWidth,t.ToolSelected="Paint",t.isDrawingMode=!0,!0)},ImageEditor_Pan=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");return null!=t&&(t.ToolSelected="Pan",t.isDrawingMode=!1,!0)},ImageEditor_ResetZoom=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");return null!=t&&(t.setZoom(1),t.setViewportTransform([1,0,0,1,0,0]),!0)},ImageEditor_ZoomIn=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){var i=t.getZoom();(i+=.5)>10&&(i=10),i<.1&&(i=.1);var n=new fabric.Point(t.getWidth()/2,t.getHeight()/2);fabric.util.transformPoint(n,t.viewportTransform);return t.zoomToPoint(n,i),!0}return!1},ImageEditor_ZoomOut=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){var i=t.getZoom();(i-=.5)>10&&(i=10),i<.1&&(i=.1);var n=new fabric.Point(t.getWidth()/2,t.getHeight()/2);fabric.util.transformPoint(n,t.viewportTransform);return t.zoomToPoint(n,i),!0}return!1},ImageEditor_AddCircle=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){t.ToolSelected="none",t.isDrawingMode=!1;var i=new fabric.Circle({radius:20,fill:t.FillColour});return t.add(i),t.centerObject(i),t.setActiveObject(i),!0}return!1},ImageEditor_AddRectangle=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){t.ToolSelected="none",t.isDrawingMode=!1;var i=new fabric.Rect({width:40,height:40,fill:t.FillColour});return t.add(i),t.centerObject(i),t.setActiveObject(i),!0}return!1},ImageEditor_AddTriangle=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){t.ToolSelected="none",t.isDrawingMode=!1;var i=new fabric.Triangle({width:40,height:40,fill:t.FillColour});return t.add(i),t.centerObject(i),t.setActiveObject(i),!0}return!1},ImageEditor_AddEmoji=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){t.ToolSelected="none",t.isDrawingMode=!1;var i=new fabric.Text(String.fromCodePoint(128578),{fontSize:24});return t.add(i),t.centerObject(i),t.setActiveObject(i),!0}return!1},ImageEditor_AddText=function(e,t){var i=GetCanvas("contact-"+e+"-imageCanvas");if(null!=i){i.ToolSelected="none",i.isDrawingMode=!1;var n=new fabric.IText(t,{fill:i.FillColour,fontFamily:"arial",fontSize:18});return i.add(n),i.centerObject(n),i.setActiveObject(n),!0}return!1},ImageEditor_Clear=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){t.ToolSelected="none",t.isDrawingMode=!1;for(var i=t.getActiveObjects(),n=0;n<i.length;n++)t.remove(i[n]);return t.discardActiveObject(),!0}return!1},ImageEditor_ClearAll=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");if(null!=t){var i=t.backgroundImage;return t.ToolSelected="none",t.isDrawingMode=!1,t.clear(),t.backgroundImage=i,!0}return!1},ImageEditor_Cancel=function(e){console.log("Removing ImageEditor..."),$("#contact-"+e+"-imagePastePreview").empty(),RemoveCanvas("contact-"+e+"-imageCanvas"),$("#contact-"+e+"-imagePastePreview").hide()},ImageEditor_Send=function(e){var t=GetCanvas("contact-"+e+"-imageCanvas");return null!=t&&(SendImageDataMessage(e,t.toDataURL({format:"png"})),!0)};function FindSomething(e){$("#contact-"+e+"-search").toggle(),0==$("#contact-"+e+"-search").is(":visible")&&RefreshStream(FindBuddyByIdentity(e)),updateScroll(e)}var allowDradAndDrop=function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&"FormData"in window&&"FileReader"in window};function onFileDragDrop(e,t){var i=e.dataTransfer.files;console.log("You are about to upload "+i.length+" file."),$("#contact-"+t+"-ChatHistory").css("outline","none");for(var n=0;n<i.length;n++){var a=i[n],o=new FileReader;o.onload=function(e){a.size<=52428800?SendFileDataMessage(t,e.target.result,a.name,a.size):alert("The file '"+a.name+"' is bigger than 50MB, you cannot upload this file")},console.log("Adding: "+a.name+" of size: "+a.size+"bytes"),o.readAsDataURL(a)}preventDefault(e)}function cancelDragDrop(e,t){$("#contact-"+t+"-ChatHistory").css("outline","none"),preventDefault(e)}function setupDragDrop(e,t){$("#contact-"+t+"-ChatHistory").css("outline","2px dashed #184369"),preventDefault(e)}function preventDefault(e){e.preventDefault(),e.stopPropagation()}function Alert(e,t,i){$("#jg_popup_l").empty(),$("#jg_popup_b").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close();var n="<div class=NoSelect>";n+='<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>',n+='<div class=UiText style="padding: 0px 10px 8px 10px;" id=AllertMessageText>'+e+"</div>",n+="</div>",$.jeegoopopup.open({title:t,html:n,width:"260",height:"auto",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"confirmDelContact",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append('<div id=bottomButtons><button id=AlertOkButton style="width:80px">'+lang.ok+"</button></div>"),$("#AlertOkButton").click((function(){console.log("Alert OK clicked"),i&&i()})),$(window).resize((function(){$.jeegoopopup.center()})),$("#closeImg").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#AlertOkButton").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($.jeegoopopup.close(),$("#jg_popup_b").empty())}))}function AlertConfigExtWindow(e,t){$("#jg_popup_l").empty(),$("#jg_popup_b").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close(),videoAudioCheck=1;var i="<div class=NoSelect>";i+='<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>',i+='<div class=UiText style="padding: 10px" id=AllertMessageText>'+e+"</div>",i+="</div>",$.jeegoopopup.open({title:t,html:i,width:"260",height:"auto",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"confirmDelContact",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append('<div id=bottomButtons><button id=AlertOkButton style="width:80px">'+lang.ok+"</button></div>"),$(window).resize((function(){$.jeegoopopup.center()})),$("#closeImg").click((function(){$("#windowCtrls").empty(),$("#jg_popup_b").empty(),$.jeegoopopup.close(),ConfigureExtensionWindow()})),$("#AlertOkButton").click((function(){console.log("Alert OK clicked"),$("#windowCtrls").empty(),$("#jg_popup_b").empty(),$.jeegoopopup.close(),ConfigureExtensionWindow()})),$("#jg_popup_overlay").click((function(){$("#windowCtrls").empty(),$("#jg_popup_b").empty(),$.jeegoopopup.close(),ConfigureExtensionWindow()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($("#windowCtrls").empty(),$("#jg_popup_b").empty(),$.jeegoopopup.close(),ConfigureExtensionWindow())}))}function Confirm(e,t,i,n){$("#jg_popup_l").empty(),$("#jg_popup_b").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close();var a="<div class=NoSelect>";a+='<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>',a+='<div class=UiText style="padding: 10px" id=ConfirmMessageText>'+e+"</div>",a+="</div>",$.jeegoopopup.open({html:a,width:"260",height:"auto",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"confirmDelContact",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append("<div id=ConfDelContact><button id=ConfirmOkButton>"+lang.ok+"</button><button id=ConfirmCancelButton>"+lang.cancel+"</button></div>"),$("#ConfirmOkButton").click((function(){console.log("Confirm OK clicked"),i&&i()})),$("#ConfirmCancelButton").click((function(){console.log("Confirm Cancel clicked"),n&&n()})),$(window).resize((function(){$.jeegoopopup.center()})),$("#closeImg").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#ConfirmOkButton").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#ConfirmCancelButton").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($.jeegoopopup.close(),$("#jg_popup_b").empty())}))}function ConfirmConfigExtWindow(e,t,i,n){$("#jg_popup_l").empty(),$("#jg_popup_b").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close();var a="<div class=NoSelect>";a+="<div id=windowCtrls><img id=closeImg src=images/3_close.svg title=Close /></div>",a+='<div class=UiText style="padding: 10px" id=ConfirmMessageText>'+e+"</div>",a+="</div>",$.jeegoopopup.open({html:a,width:"260",height:"auto",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"ConfCloseAccount",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append("<div id=ConfCloseAccount><button id=ConfirmOkButton>"+lang.close_user_account+"</button><button id=ConfirmCancelButton>"+lang.cancel+"</button></div>"),$("#ConfirmOkButton").click((function(){console.log("Confirm OK clicked"),i&&i()})),$("#ConfirmCancelButton").click((function(){console.log("Confirm Cancel clicked"),n&&n(),$("#windowCtrls").empty(),$("#jg_popup_b").empty(),$.jeegoopopup.close(),ConfigureExtensionWindow()})),$(window).resize((function(){$.jeegoopopup.center()})),$("#closeImg").click((function(){$("#jg_popup_b").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close(),ConfigureExtensionWindow()}))}function Prompt(e,t,i,n,a,o,l,s){$("#jg_popup_l").empty(),$("#jg_popup_b").empty(),$("#windowCtrls").empty(),$.jeegoopopup.close();var r="<div class=NoSelect>";r+='<div id="windowCtrls"><img id="closeImg" src="images/3_close.svg" title="Close" /></div>',r+='<div class=UiText style="padding: 10px" id=PromptMessageText>',r+=e,r+='<div style="margin-top:10px">'+i+" : </div>",r+='<div style="margin-top:5px"><INPUT id=PromptValueField type='+a+' value="'+n+'" placeholder="'+o+'" style="width:98%"></div>',r+="</div>",r+="</div>",$.jeegoopopup.open({html:r,width:"260",height:"auto",center:!0,scrolling:"no",skinClass:"jg_popup_basic",contentClass:"confirmDelContact",overlay:!0,opacity:50,draggable:!0,resizable:!1,fadeIn:0}),$("#jg_popup_b").append('<div id=bottomButtons><button id=PromptOkButton style="width:80px">'+lang.ok+'</button> <button id=PromptCancelButton class=UiButton style="width:80px">'+lang.cancel+"</button></div>"),$("#PromptOkButton").click((function(){console.log("Prompt OK clicked, with value: "+$("#PromptValueField").val()),l&&l($("#PromptValueField").val())})),$("#PromptCancelButton").click((function(){console.log("Prompt Cancel clicked"),s&&s()})),$(window).resize((function(){$.jeegoopopup.center()})),$("#closeImg").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#PromptOkButton").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#PromptCancelButton").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$("#jg_popup_overlay").click((function(){$.jeegoopopup.close(),$("#jg_popup_b").empty()})),$(window).on("keydown",(function(e){"Escape"==e.key&&($.jeegoopopup.close(),$("#jg_popup_b").empty())}))}function DetectDevices(){navigator.mediaDevices.enumerateDevices().then((function(e){HasVideoDevice=!1,HasAudioDevice=!1,HasSpeakerDevice=!1,AudioinputDevices=[],VideoinputDevices=[],SpeakerDevices=[];for(var t=0;t<e.length;++t)"audioinput"===e[t].kind?(HasAudioDevice=!0,AudioinputDevices.push(e[t])):"audiooutput"===e[t].kind?(HasSpeakerDevice=!0,SpeakerDevices.push(e[t])):"videoinput"===e[t].kind&&(HasVideoDevice=!0,VideoinputDevices.push(e[t]))})).catch((function(e){console.error("Error enumerating devices",e)}))}DetectDevices(),window.setInterval((function(){DetectDevices()}),1e4); |
|
0 | 2 |
\ No newline at end of file |
1 | 3 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,314 @@ |
1 |
+{ |
|
2 |
+ "account_settings" : "Settings", |
|
3 |
+ "create_group" : "Create Group", |
|
4 |
+ "add_someone" : "Add Someone", |
|
5 |
+ "add_contact" : "Add Contact", |
|
6 |
+ "find_someone" : "Find contact ...", |
|
7 |
+ "refresh_registration" : "Refresh Registration", |
|
8 |
+ "configure_extension" : "Configure Extension", |
|
9 |
+ "configure_account" : "Configure Account", |
|
10 |
+ "auto_answer" : "Auto Answer", |
|
11 |
+ "do_not_disturb" : "Do Not Disturb", |
|
12 |
+ "call_waiting" : "Call Waiting", |
|
13 |
+ "record_all_calls" : "Record All Calls", |
|
14 |
+ "log_out" : "Log Out", |
|
15 |
+ "logged_in_as" : "You are logged in as", |
|
16 |
+ "extension_number" : "Extension Number", |
|
17 |
+ "email" : "Email", |
|
18 |
+ "mobile" : "Mobile", |
|
19 |
+ "alternative_contact" : "Alternate Contact", |
|
20 |
+ "full_name" : "Full Name", |
|
21 |
+ "display_name": "Display Name", |
|
22 |
+ "eg_full_name" : "Eg: John Doe", |
|
23 |
+ "eg_display_name" : "Eg: John Doe", |
|
24 |
+ "title_description" : "Title / Description", |
|
25 |
+ "eg_general_manager" : "Eg: General Manager", |
|
26 |
+ "internal_subscribe_extension" : "Extension (Internal)", |
|
27 |
+ "eg_internal_subscribe_extension" : "eg: 100 or john", |
|
28 |
+ "mobile_number" : "Mobile Number", |
|
29 |
+ "eg_mobile_number" : "Eg: +497201234567", |
|
30 |
+ "eg_email" : "Eg: john.doe@domain.com", |
|
31 |
+ "contact_number_1" : "Contact Number 1", |
|
32 |
+ "eg_contact_number_1" : "Eg: +499876543210", |
|
33 |
+ "contact_number_2" : "Contact Number 2", |
|
34 |
+ "eg_contact_number_2" : "Eg: +491234567890", |
|
35 |
+ "add" : "Add", |
|
36 |
+ "cancel" : "Cancel", |
|
37 |
+ "save" : "Save", |
|
38 |
+ "remove": "Remove", |
|
39 |
+ "reload_required" : "Reload Required", |
|
40 |
+ "alert_settings" : "In order to apply these settings, the page must reload, OK?", |
|
41 |
+ "account" : "Account", |
|
42 |
+ "audio_video" : "Audio & Video", |
|
43 |
+ "appearance" : "Appearance", |
|
44 |
+ "notifications" : "Notifications", |
|
45 |
+ "email_integration": "Email integration", |
|
46 |
+ "enable_roundcube_integration": "Enable Roundcube email integration (To enable this you need to also enable the plugins 'autologon' and 'autologout' in Roundcube).", |
|
47 |
+ "roundcube_domain": "Roundcube domain", |
|
48 |
+ "rc_basic_auth_user": "Roundcube basic authentication username (if basic auth is configured)(basic auth will work in Firefox but not in Chrome)", |
|
49 |
+ "rc_basic_auth_password": "Roundcube basic authentication password (if basic auth is configured)(basic auth will work in Firefox but not in Chrome)", |
|
50 |
+ "roundcube_user": "Roundcube user", |
|
51 |
+ "roundcube_password": "Roundcube password", |
|
52 |
+ "change_user_password" : "Change Password", |
|
53 |
+ "current_user_password" : "Current Password", |
|
54 |
+ "new_user_password" : "New Password", |
|
55 |
+ "repeat_new_user_password": "Repeat New Password", |
|
56 |
+ "change_user_email" : "Change Email", |
|
57 |
+ "current_user_email" : "Current Email", |
|
58 |
+ "new_user_email" : "New Email", |
|
59 |
+ "repeat_new_user_email" : "Repeat New Email", |
|
60 |
+ "close_user_account" : "Close Account", |
|
61 |
+ "if_you_want_to_close_account" : "If you want to close your Roundpin user account click on the button from below", |
|
62 |
+ "asterisk_server_address" : "WebSocket Domain", |
|
63 |
+ "eg_asterisk_server_address" : "Eg: roundpin.example.com", |
|
64 |
+ "websocket_port" : "WebSocket Port", |
|
65 |
+ "eg_websocket_port" : "Eg: 8089", |
|
66 |
+ "websocket_path" : "WebSocket Path", |
|
67 |
+ "eg_websocket_path" : "Eg: /ws", |
|
68 |
+ "sip_username" : "SIP Username", |
|
69 |
+ "eg_sip_username" : "Eg: 601", |
|
70 |
+ "sip_password" : "SIP Password", |
|
71 |
+ "eg_sip_password" : "Eg: y2G5vEz6Q8l9U2RsC", |
|
72 |
+ "stun_server" : "STUN server domain or IPv4 address, and port number", |
|
73 |
+ "speaker" : "Speaker", |
|
74 |
+ "microphone" : "Microphone", |
|
75 |
+ "camera" : "Camera", |
|
76 |
+ "frame_rate" : "Frame Rate (per second)", |
|
77 |
+ "quality" : "Quality", |
|
78 |
+ "image_orientation" : "Image Orientation", |
|
79 |
+ "aspect_ratio" : "Aspect Ratio", |
|
80 |
+ "preview" : "Preview", |
|
81 |
+ "ringtone" : "Ringtone", |
|
82 |
+ "ring_device" : "Ring Device", |
|
83 |
+ "video_conference_extension" : "Video Conference Extension", |
|
84 |
+ "video_conference_extension_example" : "Eg: 789", |
|
85 |
+ "video_conference_window_width" : "Percent of screen width that the video conference windows will have", |
|
86 |
+ "video_conf_window_width_explanation" : "Eg: enter 32 to make windows 32% of screen width", |
|
87 |
+ "auto_gain_control" : "Auto Gain Control", |
|
88 |
+ "echo_cancellation" : "Echo Cancellation", |
|
89 |
+ "noise_suppression" : "Noise Suppression", |
|
90 |
+ "enable_onscreen_notifications" : "Enabled Onscreen Notifications", |
|
91 |
+ "alert_notification_permission" : "You need to accept the permission request to allow Notifications", |
|
92 |
+ "permission" : "Permission", |
|
93 |
+ "error" : "Error", |
|
94 |
+ "alert_media_devices" : "MediaDevices was null - Check if your connection is secure (HTTPS)", |
|
95 |
+ "alert_error_user_media" : "Error getting User Media.", |
|
96 |
+ "alert_file_size" : "The file is bigger than 50MB, you cannot upload this file", |
|
97 |
+ "alert_single_file" : "Select a single file", |
|
98 |
+ "alert_not_found" : "This item was not found", |
|
99 |
+ "edit" : "Edit", |
|
100 |
+ "edit_contact" : "Edit Contact", |
|
101 |
+ "welcome" : "Welcome", |
|
102 |
+ "accept" : "Accept", |
|
103 |
+ "error_user_agant" : "Error creating User Agent", |
|
104 |
+ "registered" : "Registered", |
|
105 |
+ "registration_failed" : "Registration Failed", |
|
106 |
+ "unregistered" : "Unregistered, bye!", |
|
107 |
+ "connected_to_web_socket" : "Connected to Web Socket!", |
|
108 |
+ "disconnected_from_web_socket" : "Disconnected from Web Socket!", |
|
109 |
+ "web_socket_error" : "Web Socket Error", |
|
110 |
+ "connecting_to_web_socket" : "Connecting to Web Socket...", |
|
111 |
+ "error_connecting_web_socket" : "Error connecting to the server on the WebSocket port", |
|
112 |
+ "sending_registration" : "Sending Registration...", |
|
113 |
+ "unsubscribing" : "Unsubscribing...", |
|
114 |
+ "disconnecting" : "Disconnecting...", |
|
115 |
+ "incomming_call" : "Roundpin Incoming Call", |
|
116 |
+ "incomming_call_from" : "Incoming call from:", |
|
117 |
+ "answer_call" : "Answer Call", |
|
118 |
+ "answer_call_with_video" : "Answer Call with Video", |
|
119 |
+ "reject_call" : "Reject Call", |
|
120 |
+ "call_failed" : "Call Failed", |
|
121 |
+ "alert_no_microphone" : "Sorry, you don't have any Microphone connected to this computer. You cannot receive calls.", |
|
122 |
+ "call_in_progress" : "Call in Progress!", |
|
123 |
+ "call_rejected" : "Call Rejected", |
|
124 |
+ "trying" : "Trying...", |
|
125 |
+ "ringing" : "Ringing...", |
|
126 |
+ "call_cancelled" : "Call Cancelled", |
|
127 |
+ "call_ended" : "Call ended, bye!", |
|
128 |
+ "yes" : "Yes", |
|
129 |
+ "no" : "No", |
|
130 |
+ "receive_kilobits_per_second" : "Receive Kilobits per second", |
|
131 |
+ "receive_packets_per_second" : "Receive Packets per second", |
|
132 |
+ "receive_packet_loss" : "Receive Packet Loss", |
|
133 |
+ "receive_jitter" : "Receive Jitter", |
|
134 |
+ "receive_audio_levels" : "Receive Audio Levels", |
|
135 |
+ "send_kilobits_per_second" : "Send Kilobits Per Second", |
|
136 |
+ "send_packets_per_second" : "Send Packets Per Second", |
|
137 |
+ "state_not_online" : "Not online", |
|
138 |
+ "state_ready" : "Ready", |
|
139 |
+ "state_on_the_phone" : "On the phone", |
|
140 |
+ "state_ringing" : "Ringing", |
|
141 |
+ "state_on_hold" : "On hold", |
|
142 |
+ "state_unavailable" : "Unavailable", |
|
143 |
+ "state_unknown" : "Unknown", |
|
144 |
+ "alert_empty_text_message" : "Please enter a message in the provided text box or select a file to send, then click the paper plane button on the right, or press Ctrl + Enter, to send the message and/or the file.", |
|
145 |
+ "no_message" : "No Message", |
|
146 |
+ "message_from" : "Message from", |
|
147 |
+ "starting_video_call" : "Starting Video Call...", |
|
148 |
+ "call_extension" : "Call Extension", |
|
149 |
+ "call_mobile" : "Call Mobile", |
|
150 |
+ "call_number" : "Call Number", |
|
151 |
+ "call_group" : "Call Group", |
|
152 |
+ "starting_audio_call" : "Starting Audio Call...", |
|
153 |
+ "call_recording_started" : "Call Recording Started", |
|
154 |
+ "call_recording_stopped" : "Call Recording Stopped", |
|
155 |
+ "confirm_stop_recording" : "Are you sure you want to stop recording this call?", |
|
156 |
+ "dial_number" : "Dial Number", |
|
157 |
+ "stop_recording" : "Stop Recording?", |
|
158 |
+ "width" : "Width", |
|
159 |
+ "height" : "Height", |
|
160 |
+ "extension" : "Extension", |
|
161 |
+ "call_blind_transfered" : "Call Blind Transfered", |
|
162 |
+ "connecting" : "Connecting...", |
|
163 |
+ "attended_transfer_call_started" : "Attended Transfer Call Started...", |
|
164 |
+ "attended_transfer_call_cancelled" : "Attended Transfer Call Cancelled", |
|
165 |
+ "attended_transfer_complete_accepted" : "Attended Transfer Complete (Accepted)", |
|
166 |
+ "attended_transfer_complete" : "Attended Transfer complete", |
|
167 |
+ "attended_transfer_call_ended" : "Attended Transfer Call Ended", |
|
168 |
+ "attended_transfer_call_rejected" : "Attended Transfer Call Rejected", |
|
169 |
+ "attended_transfer_call_terminated" : "Attended Transfer Call Terminated", |
|
170 |
+ "launch_video_conference" : "Launch Video Conference", |
|
171 |
+ "conference_call_started" : "Conference Call Started...", |
|
172 |
+ "canference_call_cancelled" : "Conference Call Cancelled", |
|
173 |
+ "conference_call_in_progress" : "Conference Call In Progress", |
|
174 |
+ "conference_call_ended" : "Conference Call Ended", |
|
175 |
+ "conference_call_rejected" : "Conference Call Rejected", |
|
176 |
+ "conference_call_terminated" : "Conference Call Terminated", |
|
177 |
+ "null_session" : "Session Error, Null", |
|
178 |
+ "call_on_hold" : "Call on Hold", |
|
179 |
+ "send_dtmf" : "Sent DTMF", |
|
180 |
+ "switching_video_source" : "Switching video source", |
|
181 |
+ "switching_to_canvas" : "Switching to canvas", |
|
182 |
+ "switching_to_shared_video" : "Switching to Shared Video", |
|
183 |
+ "switching_to_shared_screeen" : "Switching to Shared Screen", |
|
184 |
+ "video_disabled" : "Video Disabled", |
|
185 |
+ "line" : "Line", |
|
186 |
+ "back" : "Back", |
|
187 |
+ "send_email" : "Send Email", |
|
188 |
+ "audio_call" : "Audio Call", |
|
189 |
+ "video_call" : "Video Call", |
|
190 |
+ "find_something" : "Find in Message Stream", |
|
191 |
+ "send_chat_message": "Send Message", |
|
192 |
+ "save_chat_text": "Save Chat Text", |
|
193 |
+ "remove" : "Remove", |
|
194 |
+ "remove_contact" : "Remove Contact", |
|
195 |
+ "present" : "Present", |
|
196 |
+ "scratchpad" : "Scratchpad", |
|
197 |
+ "screen" : "Screen", |
|
198 |
+ "video" : "Video", |
|
199 |
+ "blank" : "Blank", |
|
200 |
+ "show_key_pad" : "Show Key Pad", |
|
201 |
+ "mute" : "Mute", |
|
202 |
+ "unmute" : "Unmute", |
|
203 |
+ "start_call_recording" : "Start Call Recording", |
|
204 |
+ "stop_call_recording" : "Stop Call Recording", |
|
205 |
+ "transfer_call" : "Transfer Call", |
|
206 |
+ "cancel_transfer" : "Cancel Transfer", |
|
207 |
+ "conference_call" : "Conference Call", |
|
208 |
+ "cancel_conference" : "Cancel Conference", |
|
209 |
+ "hold_call" : "Hold Call", |
|
210 |
+ "resume_call" : "Resume Call", |
|
211 |
+ "end_call" : "End Call", |
|
212 |
+ "search_or_enter_number" : "Search or enter number", |
|
213 |
+ "blind_transfer" : "Blind Transfer", |
|
214 |
+ "attended_transfer" : "Attended Transfer", |
|
215 |
+ "complete_transfer" : "Complete Transfer", |
|
216 |
+ "end_transfer_call" : "End Transfer Call", |
|
217 |
+ "call" : "Call", |
|
218 |
+ "cancel_call" : "Cancel Call", |
|
219 |
+ "join_conference_call" : "Join Conference Call", |
|
220 |
+ "end_conference_call" : "End Conference Call", |
|
221 |
+ "microphone_levels" : "Microphone Levels", |
|
222 |
+ "speaker_levels" : "Speaker Levels", |
|
223 |
+ "send_statistics" : "Send Statistics", |
|
224 |
+ "receive_statistics" : "Receive Statistics", |
|
225 |
+ "find_something_in_the_message_stream" : "Find in message stream ...", |
|
226 |
+ "type_your_message_here" : "Type the message here, then click the paper plane button on the right or press Ctrl + Enter to send it.", |
|
227 |
+ "menu" : "Menu", |
|
228 |
+ "confirm_remove_buddy" : "Are you sure you want to remove this contact from your contacts list and from the database ? This action cannot be undone. Click 'OK' to remove the contact or 'Cancel' to cancel.", |
|
229 |
+ "remove_buddy" : "Remove Contact", |
|
230 |
+ "confirm_close_account" : "Are you sure you want to close your Roundpin user account ? Click 'OK' to close your Roundpin user account, or 'Cancel' to cancel.", |
|
231 |
+ "close_user_account" : "Close Account", |
|
232 |
+ "close_roundpin_user_account" : "Close Roundpin User Account", |
|
233 |
+ "read_more" : "Read More", |
|
234 |
+ "started" : "Started", |
|
235 |
+ "stopped" : "Stopped", |
|
236 |
+ "recording_duration" : "Recording Duration", |
|
237 |
+ "a_video_call" : "a video call", |
|
238 |
+ "an_audio_call" : "an audio call", |
|
239 |
+ "you_tried_to_make" : "You tried to make", |
|
240 |
+ "you_made" : "You made", |
|
241 |
+ "and_spoke_for" : "and spoke for", |
|
242 |
+ "you_missed_a_call" : "Missed call", |
|
243 |
+ "you_recieved" : "You received", |
|
244 |
+ "second_single" : "second", |
|
245 |
+ "seconds_plural" : "seconds", |
|
246 |
+ "minute_single" : "minute", |
|
247 |
+ "minutes_plural" : "minutes", |
|
248 |
+ "hour_single" : "hour", |
|
249 |
+ "hours_plural" : "hours", |
|
250 |
+ "bytes" : "Bytes", |
|
251 |
+ "kb" : "KB", |
|
252 |
+ "mb" : "MB", |
|
253 |
+ "gb" : "GB", |
|
254 |
+ "tb" : "TB", |
|
255 |
+ "pb" : "PB", |
|
256 |
+ "eb" : "EB", |
|
257 |
+ "zb" : "ZB", |
|
258 |
+ "yb" : "YB", |
|
259 |
+ "call_on_mute" : "Call on Mute", |
|
260 |
+ "call_off_mute" : "Call off Mute", |
|
261 |
+ "tag_call" : "Tag Call", |
|
262 |
+ "clear_flag" : "Clear Flag", |
|
263 |
+ "flag_call" : "Flag Call", |
|
264 |
+ "edit_comment" : "Edit Comment", |
|
265 |
+ "copy_message" : "Copy Message", |
|
266 |
+ "quote_message" : "Quote Message", |
|
267 |
+ "select_expression" : "Select Emoticon", |
|
268 |
+ "send_file": "Send File", |
|
269 |
+ "dictate_message" : "Dictate Message", |
|
270 |
+ "alert_speech_recognition" : "Your browser does not support this function, sorry", |
|
271 |
+ "speech_recognition" : "Speech Recognition", |
|
272 |
+ "im_listening" : "I'm listening...", |
|
273 |
+ "msg_silence_detection": "You were quiet for a while so voice recognition turned itself off.", |
|
274 |
+ "msg_no_speech": "No speech was detected. Try again.", |
|
275 |
+ "loading": "Loading...", |
|
276 |
+ "select_video": "Select Video", |
|
277 |
+ "ok": "OK", |
|
278 |
+ "device_settings" : "Device Settings", |
|
279 |
+ "call_stats" : "Call Stats", |
|
280 |
+ "you_received_a_call_from" : "You received a call from", |
|
281 |
+ "you_made_a_call_to" : "You made a call to", |
|
282 |
+ "you_answered_after" : "You answered after", |
|
283 |
+ "they_answered_after" : "They answered after", |
|
284 |
+ "with_video" : "with video", |
|
285 |
+ "you_started_a_blind_transfer_to" : "You started a blind transfer to", |
|
286 |
+ "you_started_an_attended_transfer_to" : "You started an attended transfer to", |
|
287 |
+ "the_call_was_completed" : "The call was completed.", |
|
288 |
+ "the_call_was_not_completed" : "The call was not completed.", |
|
289 |
+ "you_put_the_call_on_mute" : "You put the call on mute.", |
|
290 |
+ "you_took_the_call_off_mute" : "You took the call off mute.", |
|
291 |
+ "you_put_the_call_on_hold" : "You put the call on hold.", |
|
292 |
+ "you_took_the_call_off_hold" : "You took the call off hold.", |
|
293 |
+ "call_is_being_recorded" : "Call is being recorded.", |
|
294 |
+ "now_stopped" : "Now Stopped", |
|
295 |
+ "you_started_a_conference_call_to" : "You started a conference call to", |
|
296 |
+ "show_call_detail_record" : "Show Call Detail Record", |
|
297 |
+ "call_detail_record" : "Call Detail Record", |
|
298 |
+ "call_direction" : "Call Direction", |
|
299 |
+ "call_date_and_time" : "Call Date & Time", |
|
300 |
+ "ring_time" : "Ring Time", |
|
301 |
+ "talk_time" : "Talk Time", |
|
302 |
+ "call_duration" : "Call Duration", |
|
303 |
+ "flagged" : "Flagged", |
|
304 |
+ "call_tags" : "Call Tags", |
|
305 |
+ "call_notes" : "Call Notes", |
|
306 |
+ "activity_timeline" : "Activity Timeline", |
|
307 |
+ "call_recordings" : "Call Recordings", |
|
308 |
+ "save_as" : "Save As", |
|
309 |
+ "right_click_and_select_save_link_as" : "Right click and select Save Link As", |
|
310 |
+ "send" : "Send", |
|
311 |
+ "external_conf_users" : "External Video Conference Users", |
|
312 |
+ "about" : "About", |
|
313 |
+ "about_text" : "Roundpin is a fully featured browser phone that implements audio/video calling, video conferencing and text messaging using SIP over WebSocket and WebRTC. It can connect to SIP providers via Asterisk or directly. <br><br>Version 1.0.4<br><br>You can support the continuous maintenance of Roundpin by <a href='https://www.doublebastion.com/donations' target='_blank'>donating</a>.<br>Roundpin is a component of <a href='https://www.doublebastion.com/' target='_blank'>RED SCARF Suite</a>.<br><br> Copyright © 2021 <a href='https://www.doublebastion.com/contact/' target='_blank'>Double Bastion LLC</a> <br> License: <a href='https://www.gnu.org/licenses/agpl-3.0.html' target='_blank'>GNU Affero General Public License v3.0</a><br><br><a href='https://www.doublebastion.com/roundpin/' target='_blank'>Web page<a><br><a href='https://git.doublebastion.com/roundpin/' target='_blank'>Repository</a>" |
|
314 |
+} |