/** * Copyright (C) 2021 Double Bastion LLC * * This file is part of Roundpin, which is licensed under the * GNU Affero General Public License Version 3.0. The license terms * are detailed in the "LICENSE.txt" file located in the root directory. * * This is a modified version of the original file * "phone.js", first modified in 2020. * * The original "phone.js" file was written by Conrad de Wet. * We thank Conrad de Wet for his work and we list below * the copyright notice of the original "phone.js" file: /* ------------------------------------------------------------- Copyright (c) 2020 - Conrad de Wet - All Rights Reserved. ============================================================= File: phone.js License: GNU Affero General Public License v3.0 Version: 0.1.0 Owner: Conrad de Wet Date: April 2020 Git: https://github.com/InnovateAsterisk/Browser-Phone */ // Global Settings // =============== var enabledExtendedServices = false; var enabledGroupServices = false; // Lanaguage Packs (lang/xx.json) // =============== // Note: The following should correspond to files on your server. // eg: If you list "fr" then you need to add the file "fr.json". // Use the "en.json" as a template. // More specific lanagauge must be first. ie: "zh-hans" should be before "zh". // "en.json" is always loaded by default const availableLang = ["ja", "zh-hans", "zh", "ru", "tr", "nl"]; // User Settings & Defaults // ======================== var wssServer = getDbItem("wssServer", null); var profileUserID = getDbItem("profileUserID", null); var profileUser = getDbItem("profileUser", null); var profileName = getDbItem("profileName", null); var WebSocketPort = getDbItem("WebSocketPort", null); var ServerPath = getDbItem("ServerPath", null); var SipUsername = getDbItem("SipUsername", null); var SipPassword = getDbItem("SipPassword", null); var StunServer = getDbItem("StunServer", ""); var TransportConnectionTimeout = parseInt(getDbItem("TransportConnectionTimeout", 15)); // The timeout in seconds for the initial connection to make on the web socket port var TransportReconnectionAttempts = parseInt(getDbItem("TransportReconnectionAttempts", 99)); // The number of times to attempt to reconnect to a WebSocket when the connection drops. var TransportReconnectionTimeout = parseInt(getDbItem("TransportReconnectionTimeout", 15)); // The time in seconds to wait between WebSocket reconnection attempts. var userAgentStr = getDbItem("UserAgentStr", "Roundpin (SipJS - 0.11.6)"); // Set this to whatever you want. var hostingPrefex = getDbItem("HostingPrefex", ""); // Use if hosting off root directiory. eg: "/phone/" or "/static/" var RegisterExpires = parseInt(getDbItem("RegisterExpires", 300)); // Registration expiry time (in seconds) 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) 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) var IceStunCheckTimeout = parseInt(getDbItem("IceStunCheckTimeout", 500)); // Set amount of time in milliseconds to wait for the ICE/STUN server var AutoAnswerEnabled = (getDbItem("AutoAnswerEnabled", "0") == "1"); // Automatically answers the phone when the call comes in, if you are not on a call already var DoNotDisturbEnabled = (getDbItem("DoNotDisturbEnabled", "0") == "1"); // Rejects any inbound call, while allowing outbound calls var CallWaitingEnabled = (getDbItem("CallWaitingEnabled", "1") == "1"); // Rejects any inbound call if you are on a call already. var RecordAllCalls = (getDbItem("RecordAllCalls", "0") == "1"); // Starts Call Recording when a call is established. var StartVideoFullScreen = (getDbItem("StartVideoFullScreen", "1") == "0"); // Starts a vdeo call in the full screen (browser screen, not dektop) var AutoGainControl = (getDbItem("AutoGainControl", "1") == "1"); // Attempts to adjust the microphone volume to a good audio level. (OS may be better at this) var EchoCancellation = (getDbItem("EchoCancellation", "1") == "1"); // Attemots to remove echo over the line. var NoiseSuppression = (getDbItem("NoiseSuppression", "1") == "1"); // Attempts to clear the call qulity of noise. var MirrorVideo = getDbItem("VideoOrientation", "rotateY(180deg)"); // Displays the self-preview in normal or mirror view, to better present the preview. var maxFrameRate = getDbItem("FrameRate", ""); // Suggests a frame rate to your webcam if possible. var videoHeight = getDbItem("VideoHeight", ""); // Suggests a video height (and therefore picture quality) to your webcam. var videoAspectRatio = getDbItem("AspectRatio", ""); // Suggests an aspect ratio (1:1 | 4:3 | 16:9) to your webcam. var NotificationsActive = (getDbItem("Notifications", "0") == "1"); var StreamBuffer = parseInt(getDbItem("StreamBuffer", 50)); // The amount of rows to buffer in the Buddy Stream var PosterJpegQuality = parseFloat(getDbItem("PosterJpegQuality", 0.6)); // The image quality of the Video Poster images var VideoResampleSize = getDbItem("VideoResampleSize", "HD"); // The resample size (height) to re-render video that gets presented (sent). (SD = ???x360 | HD = ???x720 | FHD = ???x1080) var RecordingVideoSize = getDbItem("RecordingVideoSize", "HD"); // The size/quality of the video track in the recodings (SD = 640x360 | HD = 1280x720 | FHD = 1920x1080) var RecordingVideoFps = parseInt(getDbItem("RecordingVideoFps", 12)); // The Frame Per Second of the Video Track recording var RecordingLayout = getDbItem("RecordingLayout", "them-pnp"); // The Layout of the Recording Video Track (side-by-side | us-pnp | them-pnp | us-only | them-only) var DidLength = parseInt(getDbItem("DidLength", 6)); // DID length from which to decide if an incoming caller is a "contact" or an "extension". var MaxDidLength = parseInt(getDbItem("maximumNumberLength", 16)); // Maximum langth of any DID number including international dialled numbers. var DisplayDateFormat = getDbItem("DateFormat", "YYYY-MM-DD"); // The display format for all dates. https://momentjs.com/docs/#/displaying/ var DisplayTimeFormat = getDbItem("TimeFormat", "h:mm:ss A"); // The display format for all times. https://momentjs.com/docs/#/displaying/ 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 // Permission Settings var EnableTextMessaging = (getDbItem("EnableTextMessaging", "1") == "1"); // Enables the Text Messaging var DisableFreeDial = (getDbItem("DisableFreeDial", "0") == "1"); // Removes the Dial icon in the profile area, users will need to add buddies in order to dial. var DisableBuddies = (getDbItem("DisableBuddies", "0") == "1"); // Removes the Add Someone menu item and icon from the profile area. Buddies will still be created automatically. var EnableTransfer = (getDbItem("EnableTransfer", "1") == "1"); // Controls Transfering during a call var EnableConference = (getDbItem("EnableConference", "1") == "1"); // Controls Conference during a call var AutoAnswerPolicy = getDbItem("AutoAnswerPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on var DoNotDisturbPolicy = getDbItem("DoNotDisturbPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on var CallWaitingPolicy = getDbItem("CallWaitingPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on var CallRecordingPolicy = getDbItem("CallRecordingPolicy", "allow"); // allow = user can choose | disabled = feature is disabled | enabled = feature is always on var EnableAccountSettings = (getDbItem("EnableAccountSettings", "1") == "1"); // Controls the Account tab in Settings var EnableAudioVideoSettings = (getDbItem("EnableAudioVideoSettings", "1") == "1"); // Controls the Audio & Video tab in Settings var EnableAppearanceSettings = (getDbItem("EnableAppearanceSettings", "1") == "1"); // Controls the Appearance tab in Settings var EnableChangeUserPasswordSettings = (getDbItem("EnableChangeUserPasswordSettings", "1") == "1"); // Controls the 'Change Password' tab in Settings var EnableChangeUserEmailSettings = (getDbItem("EnableChangeUserEmailSettings", "1") == "1"); // Controls the 'Change Email' tab in Settings var EnableCloseUserAccount = (getDbItem("EnableCloseUserAccount", "1") == "1"); // Controls the 'Close Account' tab in Settings var EnableAlphanumericDial = (getDbItem("EnableAlphanumericDial", "1") == "1"); // Allows calling /[^\da-zA-Z\*\#\+]/g default is /[^\d\*\#\+]/g var EnableVideoCalling = (getDbItem("EnableVideoCalling", "1") == "1"); // Enables Video during a call var winVideoConf = null; var winVideoConfCheck = 0; // System variables // ================ var localDB = window.localStorage; var userAgent = null; var voicemailSubs = null; var BlfSubs = []; var CanvasCollection = []; var Buddies = []; var isReRegister = false; var dhtmlxPopup = null; var selectedBuddy = null; var selectedLine = null; var alertObj = null; var confirmObj = null; var promptObj = null; var windowsCollection = null; var messagingCollection = null; var HasVideoDevice = false; var HasAudioDevice = false; var HasSpeakerDevice = false; var AudioinputDevices = []; var VideoinputDevices = []; var SpeakerDevices = []; var Lines = []; var lang = {}; var audioBlobs = {}; var newLineNumber = 0; var videoAudioCheck = 0; var RCLoginCheck = 0; var decSipPass = ''; var currentChatPrivKey = ''; var sendFileCheck = 0; var upFileName = ''; var sendFileChatErr = ''; var pubKeyCheck = 0; var splitMessage = {}; // Utilities // ========= function uID(){ return Date.now()+Math.floor(Math.random()*10000).toString(16).toUpperCase(); } function utcDateNow(){ return moment().utc().format("YYYY-MM-DD HH:mm:ss UTC"); } function getDbItem(itemIndex, defaultValue){ var localDB = window.localStorage; if(localDB.getItem(itemIndex) != null) return localDB.getItem(itemIndex); return defaultValue; } function getAudioSrcID(){ var id = localDB.getItem("AudioSrcId"); return (id != null)? id : "default"; } function getAudioOutputID(){ var id = localDB.getItem("AudioOutputId"); return (id != null)? id : "default"; } function getVideoSrcID(){ var id = localDB.getItem("VideoSrcId"); return (id != null)? id : "default"; } function getRingerOutputID(){ var id = localDB.getItem("RingOutputId"); return (id != null)? id : "default"; } function formatDuration(seconds){ var sec = Math.floor(parseFloat(seconds)); if(sec < 0){ return sec; } else if(sec >= 0 && sec < 60){ return sec + " " + ((sec != 1) ? lang.seconds_plural : lang.second_single); } else if(sec >= 60 && sec < 60 * 60){ // greater then a minute and less then an hour var duration = moment.duration(sec, 'seconds'); return duration.minutes() + " "+ ((duration.minutes() != 1) ? lang.minutes_plural: lang.minute_single) +" " + duration.seconds() +" "+ ((duration.seconds() != 1) ? lang.seconds_plural : lang.second_single); } else if(sec >= 60 * 60 && sec < 24 * 60 * 60){ // greater than an hour and less then a day var duration = moment.duration(sec, 'seconds'); 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); } // Otherwise.. this is just too long } function formatShortDuration(seconds) { var sec = Math.floor(parseFloat(seconds)); if(sec < 0){ return sec; } else if(sec >= 0 && sec < 60){ return "00:"+ ((sec > 9)? sec : "0"+sec ); } else if(sec >= 60 && sec < 60 * 60){ // greater then a minute and less then an hour var duration = moment.duration(sec, 'seconds'); return ((duration.minutes() > 9)? duration.minutes() : "0"+duration.minutes()) + ":" + ((duration.seconds() > 9)? duration.seconds() : "0"+duration.seconds()); } else if(sec >= 60 * 60 && sec < 24 * 60 * 60){ // greater than an hour and less then a day var duration = moment.duration(sec, 'seconds'); 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()); } // Otherwise.. this is just too long } function formatBytes(bytes, decimals) { if (bytes === 0) return "0 "+ lang.bytes; var k = 1024; var dm = (decimals && decimals >= 0)? decimals : 2; var sizes = [lang.bytes, lang.kb, lang.mb, lang.gb, lang.tb, lang.pb, lang.eb, lang.zb, lang.yb]; var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; } function UserLocale(){ var language = window.navigator.userLanguage || window.navigator.language; // "en", "en-US", "fr", "fr-FR", "es-ES", etc. langtag = language.split('-'); if(langtag.length == 1){ return ""; } else if(langtag.length == 2) { return langtag[1].toLowerCase(); // en-US => us } else if(langtag.length >= 3) { return langtag[1].toLowerCase(); // en-US => us } } function GetAlternateLanguage() { var userLanguage = window.navigator.userLanguage || window.navigator.language; // "en", "en-US", "fr", "fr-FR", "es-ES", etc. if(Language != "auto") userLanguage = Language; userLanguage = userLanguage.toLowerCase(); if(userLanguage == "en" || userLanguage.indexOf("en-") == 0) return ""; // English is already loaded for(l = 0; l < availableLang.length; l++) { if(userLanguage.indexOf(availableLang[l].toLowerCase()) == 0) { console.log("Alternate Language detected: ", userLanguage); // Set up Moment with the same langugae settings moment.locale(userLanguage); return availableLang[l].toLowerCase(); } } return ""; } function getFilter(filter, keyword) { if(filter.indexOf(",", filter.indexOf(keyword +": ") + keyword.length + 2) != -1) { return filter.substring(filter.indexOf(keyword +": ") + keyword.length + 2, filter.indexOf(",", filter.indexOf(keyword +": ") + keyword.length + 2)); } else { return filter.substring(filter.indexOf(keyword +": ") + keyword.length + 2); } } function base64toBlob(base64Data, contentType) { if(base64Data.indexOf("," != -1)) base64Data = base64Data.split(",")[1]; // [data:image/png;base64] , [xxx...] var byteCharacters = atob(base64Data); var slicesCount = Math.ceil(byteCharacters.length / 1024); var byteArrays = new Array(slicesCount); for (var s = 0; s < slicesCount; ++s) { var begin = s * 1024; var end = Math.min(begin + 1024, byteCharacters.length); var bytes = new Array(end - begin); for (var offset = begin, i = 0; offset < end; ++i, ++offset) { bytes[i] = byteCharacters[offset].charCodeAt(0); } byteArrays[s] = new Uint8Array(bytes); } return new Blob(byteArrays, { type: contentType }); } function MakeDataArray(defaultValue, count) { var rtnArray = new Array(count); for(var i=0; i< rtnArray.length; i++) { rtnArray[i] = defaultValue; } return rtnArray; } // Save account configuration data to SQL database 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 STUNServer = $("#Configure_Account_StunServer").val(); var AUDIOOutputId = $("#playbackSrc").val(); var VIDEOSrcId = $("#previewVideoSrc").val(); var VIDEOHeight = $("input[name=Settings_Quality]:checked").val(); var FRAMERate = parseInt($("input[name=Settings_FrameRate]:checked").val()); var ASPECTRatio = $("input[name=Settings_AspectRatio]:checked").val(); var VIDEOOrientation = $("input[name=Settings_Oriteation]:checked").val(); var AUDIOSrcId = $("#microphoneSrc").val(); var AUTOGainControl = ($("#Settings_AutoGainControl").is(':checked'))? "1" : "0"; var ECHOCancellation = ($("#Settings_EchoCancellation").is(':checked'))? "1" : "0"; var NOISESuppression = ($("#Settings_NoiseSuppression").is(':checked'))? "1" : "0"; var RINGOutputId = $("#ringDevice").val(); var VideoConfExtension = $("#Video_Conf_Extension").val(); var VideoConfWindowWidth = $("#Video_Conf_Window_Width").val(); var PROFILEpicture = (typeof getDbItem("profilePicture", "") === 'undefined') ? "" : getDbItem("profilePicture", ""); var NOTIFYCheck = ($("#Settings_Notifications").is(":checked"))? 1 : 0; var EMAILIntegration = ($("#emailIntegration").is(":checked"))? 1 : 0; var RCDomain = $("#RoundcubeDomain").val(); var RCbasicauthuser = $("#rcBasicAuthUser").val(); var RCbasicauthpass = $("#rcBasicAuthPass").val(); var RCuser = $("#RoundcubeUser").val(); var RCpassword = $("#RoundcubePass").val(); if (userName != '') { if (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: STUNServer, audio_output_id: AUDIOOutputId, video_src_id: VIDEOSrcId, video_height: VIDEOHeight, frame_rate: FRAMERate, aspect_ratio: ASPECTRatio, video_orientation: VIDEOOrientation, audio_src_id: AUDIOSrcId, auto_gain_control: AUTOGainControl, echo_cancellation: ECHOCancellation, noise_suppression: NOISESuppression, ring_output_id: RINGOutputId, video_conf_extension: VideoConfExtension, video_conf_window_width: VideoConfWindowWidth, profile_picture: PROFILEpicture, notifications: NOTIFYCheck, use_roundcube: EMAILIntegration, rcdomain: RCDomain, rcbasicauthuser: RCbasicauthuser, rcbasicauthpass: RCbasicauthpass, rcuser: RCuser, rcpassword: RCpassword, s_ajax_call: validateSToken }, success: function(response) { window.location.reload(); }, error: function(response) { alert("An error occurred while attempting to save the account configuration data!"); } }); } else { alert("Fields: 'WebSocket Domain', 'WebSocket Port', 'WebSocket Path', 'SIP Username' and 'SIP Password' are required ! Please fill in all these fields !"); } } else { alert("An error occurred while attempting to save the data!"); } } // Get account configuration data from SQL database function getConfFromSqldb() { $.ajax({ type: "POST", url: "get-settings.php", dataType: "JSON", data: { username: userName, s_ajax_call: validateSToken }, success: function(datafromdb) { // Get configuration data from SQL database if (datafromdb.wss_server == null || datafromdb.web_socket_port == null || datafromdb.server_path == null || datafromdb.sip_username == null || datafromdb.sip_password == null) { ConfigureExtensionWindow(); } else { if (!localStorage.getItem('firstReLoad')) { localStorage['firstReLoad'] = true; window.setTimeout(function() { window.location.reload(); }, 200); } if (datafromdb.stun_server == null || typeof datafromdb.stun_server == 'undefined') { var stunData = ''; } else { var stunData = datafromdb.stun_server; } localDB.setItem("profileUserID", uID()); localDB.setItem("userrole", datafromdb.userrole); localDB.setItem("wssServer", datafromdb.wss_server); localDB.setItem("WebSocketPort", datafromdb.web_socket_port); localDB.setItem("ServerPath", datafromdb.server_path); localDB.setItem("profileUser", datafromdb.sip_username); localDB.setItem("profileName", datafromdb.profile_name); localDB.setItem("SipUsername", datafromdb.sip_username); localDB.setItem("SipPassword", datafromdb.sip_password); localDB.setItem("StunServer", stunData); localDB.setItem("AudioOutputId", datafromdb.audio_output_id); localDB.setItem("VideoSrcId", datafromdb.video_src_id); localDB.setItem("VideoHeight", datafromdb.video_height); localDB.setItem("FrameRate", datafromdb.frame_rate); localDB.setItem("AspectRatio", datafromdb.aspect_ratio); localDB.setItem("VideoOrientation", datafromdb.video_orientation); localDB.setItem("AudioSrcId", datafromdb.audio_src_id); localDB.setItem("AutoGainControl", datafromdb.auto_gain_control); localDB.setItem("EchoCancellation", datafromdb.echo_cancellation); localDB.setItem("NoiseSuppression", datafromdb.noise_suppression); localDB.setItem("RingOutputId", datafromdb.ring_output_id); localDB.setItem("VidConfExtension", datafromdb.video_conf_extension); localDB.setItem("VidConfWindowWidth", datafromdb.video_conf_window_width); localDB.setItem("profilePicture", datafromdb.profile_picture); localDB.setItem("Notifications", datafromdb.notifications); localDB.setItem("useRoundcube", datafromdb.use_roundcube); localDB.setItem("rcDomain", (datafromdb.rcdomain != '' && datafromdb.rcdomain != null && typeof datafromdb.rcdomain != 'undefined')? datafromdb.rcdomain : ""); localDB.setItem("rcBasicAuthUser", datafromdb.rcbasicauthuser); localDB.setItem("rcBasicAuthPass", datafromdb.rcbasicauthpass); localDB.setItem("RoundcubeUser", datafromdb.rcuser); localDB.setItem("RoundcubePass", datafromdb.rcpassword); Register(); } }, error: function(datafromdb) { alert("An error occurred while attempting to retrieve account configuration data from the database!"); } }); } // Save contact data to SQL database function saveContactToSQLDB(newPerson) { if (newPerson.length != 0) { $.ajax({ type: "POST", url: "save-contact.php", dataType: "JSON", data: { username: userName, contact_name: newPerson[0], contact_desc: newPerson[1], extension_number: newPerson[2], contact_mobile: newPerson[3], contact_num1: newPerson[4], contact_num2: newPerson[5], contact_email: newPerson[6], s_ajax_call: validateSToken }, success: function(response) { if (response.result != 'success') { alert(response.result); } }, error: function(response) { alert("An error occurred while attempting to save the contact to the database!"); } }); } else { alert("An error occurred while attempting to save the data!"); } } // Update contact data in SQL database function updateContactToSQLDB(newPerson) { if (newPerson.length != 0) { if (newPerson[7] != '' && newPerson[7] != null && typeof newPerson[7] != 'undefined') { $.ajax({ type: "POST", url: "update-contact.php", dataType: "JSON", data: { contact_name: newPerson[0], contact_desc: newPerson[1], extension_number: newPerson[2], contact_mobile: newPerson[3], contact_num1: newPerson[4], contact_num2: newPerson[5], contact_email: newPerson[6], contactDBID: newPerson[7], s_ajax_call: validateSToken }, success: function(response) { if (response.result != 'success') { alert(response.result); } }, error: function(response) { alert("An error occurred while attempting to save the data!"); } }); } else { alert("Error while attempting to retrieve contact data from the database!"); } } else { alert("An error occurred while attempting to save the data!"); } } // Save contact picture data to SQL database function saveContactPicToSQLDB(newPic) { if (newPic.length != 0) { $.ajax({ type: "POST", url: "save-update-contact-picture.php", dataType: "JSON", data: { username: userName, contact_name: newPic[0], profile_picture_c: newPic[1], s_ajax_call: validateSToken }, success: function(response) { }, error: function(response) { alert("An error occurred while attempting to save contact picture!"); } }); } else { alert("An error occurred while attempting to save contact picture!"); } } // Get contact data from SQL database function getContactsFromSQLDB() { $.ajax({ type: "POST", url: "get-contacts.php", dataType: "JSON", data: { username: userName, s_ajax_call: validateSToken }, success: function(contactsfromdb) { // Get contacts from SQL database and save them to localDB var jsonCon = InitUserBuddies(); $.each(contactsfromdb.contactsinfo, function(ind, contactrow) { var id = uID(); var dateNow = utcDateNow(); if (contactsfromdb.contactsinfo[ind].extension_number == '' || contactsfromdb.contactsinfo[ind].extension_number == null) { jsonCon.DataCollection.push( { Type: "contact", LastActivity: dateNow, ExtensionNumber: "", MobileNumber: contactsfromdb.contactsinfo[ind].contact_mobile, ContactNumber1: contactsfromdb.contactsinfo[ind].contact_num1, ContactNumber2: contactsfromdb.contactsinfo[ind].contact_num2, uID: null, cID: id, gID: null, DisplayName: contactsfromdb.contactsinfo[ind].contact_name, Position: "", Description: contactsfromdb.contactsinfo[ind].contact_desc, Email: contactsfromdb.contactsinfo[ind].contact_email, MemberCount: 0 } ); if (contactsfromdb.contactsinfo[ind].profile_picture_c != '' && contactsfromdb.contactsinfo[ind].profile_picture_c != null) { localDB.setItem("img-"+id+"-contact", contactsfromdb.contactsinfo[ind].profile_picture_c); } 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); AddBuddy(buddyObj, true, false, false); } else { jsonCon.DataCollection.push( { Type: "extension", LastActivity: dateNow, ExtensionNumber: contactsfromdb.contactsinfo[ind].extension_number, MobileNumber: contactsfromdb.contactsinfo[ind].contact_mobile, ContactNumber1: contactsfromdb.contactsinfo[ind].contact_num1, ContactNumber2: contactsfromdb.contactsinfo[ind].contact_num2, uID: id, cID: null, gID: null, DisplayName: contactsfromdb.contactsinfo[ind].contact_name, Position: contactsfromdb.contactsinfo[ind].contact_desc, Description: "", Email: contactsfromdb.contactsinfo[ind].contact_email, MemberCount: 0 } ); if (contactsfromdb.contactsinfo[ind].profile_picture_c != '' && contactsfromdb.contactsinfo[ind].profile_picture_c != null) { localDB.setItem("img-"+id+"-extension", contactsfromdb.contactsinfo[ind].profile_picture_c); } 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); AddBuddy(buddyObj, true, false, true); } }); jsonCon.TotalRows = jsonCon.DataCollection.length; localDB.setItem(profileUserID + "-Buddies", JSON.stringify(jsonCon)); UpdateUI(); PopulateBuddyList(); }, error: function(contactsfromdb) { alert("An error occurred while attempting to retrieve contacts data from the database!"); } }); } // Get external users data from SQL database function getExternalUserConfFromSqldb() { $.ajax({ type: "POST", url: "get-external-users-conf.php", dataType: "JSON", data: { username: userName, s_ajax_call: validateSToken }, success: function(extdatafromdb) { var extdatafromdbstr = JSON.stringify(extdatafromdb); if (extdatafromdbstr.length > 0) { localDB.setItem("externalUserConfElem", extdatafromdb.length); for (var t = 0; t < extdatafromdb.length; t++) { localDB.setItem("extUserExtension-"+t, extdatafromdb[t]['exten_for_external']); localDB.setItem("extUserExtensionPass-"+t, extdatafromdb[t]['exten_for_ext_pass']); localDB.setItem("confAccessLink-"+t, extdatafromdb[t]['conf_access_link']); } } }, error: function(extdatafromdb) { alert("An error occurred while attempting to retrieve external users configuration data from the database!"); } }); } // Check if there are any links for external access associated with the current username function checkExternalLinks() { 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.")) { $.ajax({ type: "POST", url: "remove-links-for-external-access.php", dataType: "JSON", data: { username: userName, s_ajax_call: validateSToken }, success: function(response) { 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(); if (winVideoConf != null) { winVideoConf.close(); } window.open('https://' + window.location.host + '/logout.php', '_self'); }, error: function(response) { alert("An error occurred while trying to remove the data from the database!"); Unregister(); console.log("Signing Out ..."); localStorage.clear(); if (winVideoConf != null) { winVideoConf.close(); } window.open('https://' + window.location.host + '/logout.php', '_self'); } }); } else { Unregister(); console.log("Signing Out ..."); localStorage.clear(); if (winVideoConf != null) { winVideoConf.close(); } window.open('https://' + window.location.host + '/logout.php', '_self'); } } // Remove contact from SQL database function deleteBuddyFromSqldb(buddyDisplayName) { $.ajax({ type: "POST", url: "remove-contact.php", dataType: "JSON", data: { username: userName, contact_name: buddyDisplayName, s_ajax_call: validateSToken }, success: function(delresult) { }, error: function(delresult) { alert("An error occurred while attempting to remove the contact from the database!"); } }); } // Save new Roundpin user password function saveNewUserPassword() { var currentPassword = $("#Current_User_Password").val(); var newPassword = $("#New_User_Password").val(); var repeatPassword = $("#Repeat_New_User_Password").val(); if (currentPassword == '' || newPassword == '' || repeatPassword == '') { alert("Please fill in all the fields!"); return; } // Verify if the new password meets constraints if (/^((?=.*\d)(?=.*[a-z])(?=.*\W).{10,})$/.test(newPassword)) { if (repeatPassword == newPassword) { $.ajax({ type: "POST", url: "save-new-user-password.php", dataType: "JSON", data: { username: userName, current_password: currentPassword, new_password: newPassword, s_ajax_call: validateSToken }, success: function(passchangemessage) { alert(passchangemessage); }, error: function(passchangemessage) { alert("An error occurred while attempting to change the user password!"); } }); } else { alert("The passwords entered in the new password fields don't match!"); } } else { 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 ! "); } } // Save new Roundpin user email function saveNewUserEmail() { var currentEmail = $("#Current_User_Email").val(); var newEmail = $("#New_User_Email").val(); var repeatEmail = $("#Repeat_New_User_Email").val(); if (currentEmail == '' || newEmail == '' || repeatEmail == '') { alert("Please fill in all the fields!"); return; } // Verify if the new email is a valid email address if (/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(newEmail)) { if (repeatEmail == newEmail) { $.ajax({ type: "POST", url: "save-new-user-email.php", dataType: "JSON", data: { username: userName, current_email: currentEmail, new_email: newEmail, s_ajax_call: validateSToken }, success: function(emailchangemessage) { alert(emailchangemessage); }, error: function(emailchangemessage) { alert("An error occurred while attempting to change the user email address!"); } }); } else { alert("The email addresses entered in the new email fields don't match!"); } } else { alert("The new email address is not a valid email address. Please enter a valid email address!"); } } // Close Roundpin user account 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(closeaccountmessage) { alert(closeaccountmessage); SignOut(); }, error: function(closeaccountmessage) { alert("An error occurred while attempting to close your user account!"); } }); }); } // Launch video conference function LaunchVideoConference() { if (winVideoConfCheck == 0) { winVideoConf = window.open('https://' + window.location.host + '/videoconference/index.php'); winVideoConfCheck = 1; } else { alert("The video conference has been launched. If you want to launch it again refresh the page, then click \"Launch Video Conference\"."); } } // Generate a new text chat key function generateChatRSAKeys(currentSIPusername) { var crypto = new JSEncrypt({default_key_size: 1024}); crypto.getKey(); var currentChatPubKey = crypto.getPublicKey(); currentChatPrivKey = crypto.getPrivateKey(); $.ajax({ type: "POST", url: "save-text-chat-pub-key.php", dataType: "JSON", data: { currentextension: currentSIPusername, currentchatpubkey: currentChatPubKey, s_ajax_call: validateSToken }, success: function() { }, error: function() { alert("An error occurred while trying to save the new text chat public key!"); } }); } // Remove the 'uploads' directory used to temporarily store files received during text chat function removeTextChatUploads(currentSIPUser) { $.ajax({ 'async': false, 'global': false, type: "POST", url: "text-chat-remove-uploaded-files.php", dataType: "JSON", data: { sipusername: currentSIPUser, s_ajax_call: validateSToken }, success: function(resresult) { if (resresult.note != 'success') { alert("An error occurred while trying to remove the text chat 'uploads' directory!"); } }, error: function(resresult) { alert("An error occurred while attempting to remove the text chat 'uploads' directory!"); } }); } // On page reload, close the video conference tab if it is opened function closeVideoConfTab() { if (winVideoConf) { winVideoConf.close(); } } // Show Email window function ShowEmailWindow() { if (getDbItem("useRoundcube", "") == 1) { $("#roundcubeFrame").remove(); $("#rightContent").show(); $(".streamSelected").each(function() { $(this).css("display", "none"); }); $("#rightContent").append(''); var rcDomain = ''; var rcBasicAuthUser = ''; var rcBasicAuthPass = ''; var rcUsername = ''; var rcPasswd = ''; $.ajax({ 'async': false, 'global': false, type: "POST", url: "get-email-info.php", dataType: "JSON", data: { username: userName, s_ajax_call: validateSToken }, success: function(datafromdb) { rcDomain = datafromdb.rcdomain; rcBasicAuthUser = encodeURIComponent(datafromdb.rcbasicauthuser); rcBasicAuthPass = encodeURIComponent(datafromdb.rcbasicauthpass); rcUsername = datafromdb.rcuser; rcPasswd = datafromdb.rcpassword; }, error: function(datafromdb) { alert("An error occurred while trying to retrieve data from the database!"); } }); if (rcBasicAuthUser != '' && rcBasicAuthPass != '') { var actionURL = "https://"+ rcBasicAuthUser +":"+ rcBasicAuthPass +"@"+ rcDomain +"/"; } else { var actionURL = "https://"+ rcDomain +"/"; } var form = '
'; form += ''; form += ''; form += ''; form += ''; form += ''; form += ''; form += '
'; $("#roundcubeFrame").append(form); if (RCLoginCheck == 0) { $("#submitButton").click(); RCLoginCheck = 1; } else { $("#roundcubeFrame").attr("src", actionURL); } } 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'"); } } // Shrink the left panel function CollapseLeftPanel() { if ($(window).width() >= 920) { if ($("#leftContent").hasClass("shrinkLeftContent")) { $("#leftContent").removeClass("shrinkLeftContent"); $("#rightContent").removeClass("widenRightContent"); $('#aboutImg').css("margin-right", "-3px"); } else { $("#leftContent").addClass("shrinkLeftContent"); $("#rightContent").addClass("widenRightContent"); $('#aboutImg').css("margin-right", "3px"); } } } // Show the 'About' window function ShowAboutWindow() { $.jeegoopopup.close(); var aboutHtml = '
'; aboutHtml += '
'; aboutHtml += '
'; aboutHtml += '
'; aboutHtml += '
'+lang.about_text+'
'; aboutHtml += '
'; $.jeegoopopup.open({ title: 'About Roundpin', html: aboutHtml, width: '640', height: '500', center: true, scrolling: 'no', skinClass: 'jg_popup_basic', overlay: true, opacity: 50, draggable: true, resizable: false, fadeIn: 0 }); $("#jg_popup_b").append(''); var maxWidth = $(window).width() - 12; var maxHeight = $(window).height() - 88; if (maxWidth < 656 || maxHeight < 500) { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#maximizeImg").hide(); $("#minimizeImg").hide(); } else { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#minimizeImg").hide(); $("#maximizeImg").show(); } $(window).resize(function() { maxWidth = $(window).width() - 12; maxHeight = $(window).height() - 88; $.jeegoopopup.center(); if (maxWidth < 656 || maxHeight < 500) { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#maximizeImg").hide(); $("#minimizeImg").hide(); } else { $.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(maxWidth).height(maxHeight); $.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(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); } // Show system notifications on incoming calls function incomingCallNote() { var incomingCallNotify = new Notification(lang.incomming_call, { icon: "../images/notification-logo.svg", body: "New incoming call !!!" }); incomingCallNotify.onclick = function (event) { return; }; if (document.hasFocus()) { return; } else { setTimeout(incomingCallNote, 8000); } } // Change page title on incoming calls function changePageTitle() { if ($(document).attr("title") == "Roundpin") { $(document).prop("title", "New call !!!"); } else { $(document).prop("title", "Roundpin"); } if (document.hasFocus()) { $(document).prop("title", "Roundpin"); return; } else { setTimeout(changePageTitle, 460); } } // Window and Document Events // ========================== $(window).on("beforeunload", function() { Unregister(); }); $(window).on("resize", function() { UpdateUI(); }); // User Interface // ============== function UpdateUI(){ if($(window).outerWidth() < 920){ // Narrow Layout if(selectedBuddy == null & selectedLine == null) { // Nobody Selected $("#rightContent").hide(); $("#leftContent").css("width", "100%"); $("#leftContent").show(); } else { $("#rightContent").css("margin-left", "0px"); $("#rightContent").show(); $("#leftContent").hide(); if(selectedBuddy != null) updateScroll(selectedBuddy.identity); } } else { // Wide Screen Layout if(selectedBuddy == null & selectedLine == null) { $("#leftContent").css("width", "320px"); $("#rightContent").css("margin-left", "0px"); $("#leftContent").show(); $("#rightContent").hide(); } else{ $("#leftContent").css("width", "320px"); $("#rightContent").css("margin-left", "320px"); $("#leftContent").show(); $("#rightContent").show(); if(selectedBuddy != null) updateScroll(selectedBuddy.identity); } } for(var l=0; l"; html += "
"; html += "
"+ lang.title_description +":
"; html += "
"; html += "
"+ lang.internal_subscribe_extension +":
"; if(numberStr && numberStr.length > 1 && numberStr.length < DidLength && numberStr.substring(0,1) != "*"){ html += "
"; } else{ html += "
"; } html += "
"+ lang.mobile_number +":
"; html += "
"; html += "
"+ lang.contact_number_1 +":
"; if(numberStr && numberStr.length > 1){ html += "
"; } else { html += "
"; } html += "
"+ lang.contact_number_2 +":
"; html += "
"; html += "
"+ lang.email +":
"; html += "
"; html += "" $.jeegoopopup.open({ title: 'Add Contact', html: html, width: '640', height: '500', center: true, scrolling: 'no', skinClass: 'jg_popup_basic', contentClass: 'addContactPopup', overlay: true, opacity: 50, draggable: true, resizable: false, fadeIn: 0 }); $("#jg_popup_b").append("
"); $("#save_button").click(function() { var currentASName = $("#AddSomeone_Name").val(); if (currentASName != null && currentASName.trim() !== '') { if (/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(currentASName)) { var currentDesc = $("#AddSomeone_Desc").val(); if (currentDesc != null && currentDesc.trim() !== '') { if (/^[A-Za-z0-9\s\-\.\'\"\[\]\(\)\{\}\_\!\?\~\@\%\^\&\*\+\>\<\;\:\=]+$/.test(currentDesc)) { var finCurrentDesc = currentDesc; } else { var finCurrentDesc = ''; alert('The title/description that you entered is not valid!'); } } else { var finCurrentDesc = ''; } var currentExtension = $("#AddSomeone_Exten").val(); if (currentExtension != null && currentExtension.trim() !== '') { if (/^[a-zA-Z0-9\*\#]+$/.test(currentExtension)) { var finCurrentExtension = currentExtension; } else { var finCurrentExtension = ''; alert("The extension that you entered in the 'Extension (Internal)' field is not a valid extension!"); } } else { var finCurrentExtension = ''; } var currentMobile = $("#AddSomeone_Mobile").val(); if (currentMobile != null && currentMobile.trim() !== '') { if (/^[0-9\s\+\#]+$/.test(currentMobile)) { var finCurrentMobile = currentMobile; } else { 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."); } } else { var finCurrentMobile = ''; } var currentNum1 = $("#AddSomeone_Num1").val(); if (currentNum1 != null && currentNum1.trim() !== '') { if (/^[0-9\s\+\#]+$/.test(currentNum1)) { var finCurrentNum1 = currentNum1; } else { 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."); } } else { var finCurrentNum1 = ''; } var currentNum2 = $("#AddSomeone_Num2").val(); if (currentNum2 != null && currentNum2.trim() !== '') { if (/^[0-9\s\+\#]+$/.test(currentNum2)) { var finCurrentNum2 = currentNum2; } else { 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."); } } else { var finCurrentNum2 = ''; } var currentEmail = $("#AddSomeone_Email").val(); if (currentEmail != null && currentEmail.trim() !== '') { if (/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(currentEmail)) { var finCurrentEmail = currentEmail; } else { var finCurrentEmail = ''; alert("The email that you entered is not a valid email address!"); } } else { var finCurrentEmail = ''; } // Add Contact / Extension var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies")); if(json == null) json = InitUserBuddies(); if(finCurrentExtension == ''){ // Add Regular Contact var id = uID(); var dateNow = utcDateNow(); json.DataCollection.push( { Type: "contact", LastActivity: dateNow, ExtensionNumber: "", MobileNumber: finCurrentMobile, ContactNumber1: finCurrentNum1, ContactNumber2: finCurrentNum2, uID: null, cID: id, gID: null, DisplayName: currentASName, Position: "", Description: finCurrentDesc, Email: finCurrentEmail, MemberCount: 0 } ); var newPerson = []; newPerson = [currentASName, finCurrentDesc, "", finCurrentMobile, finCurrentNum1, finCurrentNum2, finCurrentEmail]; saveContactToSQLDB(newPerson); var buddyObj = new Buddy("contact", id, currentASName, "", finCurrentMobile, finCurrentNum1, finCurrentNum2, dateNow, finCurrentDesc, finCurrentEmail); AddBuddy(buddyObj, false, false, false); } else { // Add Extension var id = uID(); var dateNow = utcDateNow(); json.DataCollection.push( { Type: "extension", LastActivity: dateNow, ExtensionNumber: finCurrentExtension, MobileNumber: finCurrentMobile, ContactNumber1: finCurrentNum1, ContactNumber2: finCurrentNum2, uID: id, cID: null, gID: null, DisplayName: currentASName, Position: finCurrentDesc, Description: "", Email: finCurrentEmail, MemberCount: 0 } ); var newPerson = []; newPerson = [currentASName, finCurrentDesc, finCurrentExtension, finCurrentMobile, finCurrentNum1, finCurrentNum2, finCurrentEmail]; saveContactToSQLDB(newPerson); var buddyObj = new Buddy("extension", id, currentASName, finCurrentExtension, finCurrentMobile, finCurrentNum1, finCurrentNum2, dateNow, finCurrentDesc, finCurrentEmail); AddBuddy(buddyObj, false, false, true); } // Update Size: json.TotalRows = json.DataCollection.length; // Save To Local DB localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json)); 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 maxWidth = $(window).width() - 12; var maxHeight = $(window).height() - 110; if (maxWidth < 656 || maxHeight < 500) { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#maximizeImg").hide(); $("#minimizeImg").hide(); } else { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#minimizeImg").hide(); $("#maximizeImg").show(); } $(window).resize(function() { maxWidth = $(window).width() - 16; maxHeight = $(window).height() - 110; $.jeegoopopup.center(); if (maxWidth < 656 || maxHeight < 500) { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#maximizeImg").hide(); $("#minimizeImg").hide(); } else { $.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(maxWidth).height(maxHeight); $.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(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } }); } function CreateGroupWindow(){ } function closeVideoAudio() { var localVideo = $("#local-video-preview").get(0); try{ var tracks = localVideo.srcObject.getTracks(); tracks.forEach(function(track) { track.stop(); }); localVideo.srcObject = null; } catch(e){} try{ var tracks = window.SettingsMicrophoneStream.getTracks(); tracks.forEach(function(track) { track.stop(); }); } catch(e){} window.SettingsMicrophoneStream = null; try{ var soundMeter = window.SettingsMicrophoneSoundMeter; soundMeter.stop(); } catch(e){} window.SettingsMicrophoneSoundMeter = null; try{ window.SettingsOutputAudio.pause(); } catch(e){} window.SettingsOutputAudio = null; try{ var tracks = window.SettingsOutputStream.getTracks(); tracks.forEach(function(track) { track.stop(); }); } catch(e){} window.SettingsOutputStream = null; try{ var soundMeter = window.SettingsOutputStreamMeter; soundMeter.stop(); } catch(e){} window.SettingsOutputStreamMeter = null; return true; } function ConfigureExtensionWindow() { $("#settingsCMenu").hide(); $.jeegoopopup.close(); var configWindow = "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"+ lang.asterisk_server_address +": *
"; configWindow += "
"; configWindow += "
"+ lang.websocket_port +": *
"; configWindow += "
"; configWindow += "
"+ lang.websocket_path +": *
"; configWindow += "
"; configWindow += "
"+ lang.display_name +": *
"; var escapedDisplayName = 'value="' + getDbItem("profileName", "").replace("'","\'") + '"'; configWindow += "
"; configWindow += "
"+ lang.sip_username +": *
"; configWindow += "
"; configWindow += "
"+ lang.sip_password +": *
"; configWindow += "
"; configWindow += "
"+ lang.stun_server +":
"; configWindow += "
"; configWindow += "

* Required field.



"; configWindow += "
"; configWindow += "
"+ lang.speaker +":
"; configWindow += "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"+ lang.ring_device +":
"; configWindow += "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"+ lang.microphone +":
"; configWindow += "
"; configWindow += "
"; configWindow += "

"; configWindow += "
"; configWindow += "
"; configWindow += "
"+ lang.camera +":
"; configWindow += "
"; configWindow += "
"+ lang.frame_rate +":
" configWindow += "
"; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += "
"; configWindow += "

"+ lang.quality +":
"; configWindow += "
"; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += "
"; configWindow += "

"+ lang.image_orientation +":
"; configWindow += "
"; configWindow += ""; configWindow += ""; configWindow += "
"; configWindow += "

"+ lang.aspect_ratio +":
"; configWindow += "
"; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += ""; configWindow += "
"; configWindow += "

"+ lang.preview +":
"; configWindow += "
"; configWindow += "
"+ lang.video_conference_extension +":
"; configWindow += "
"; configWindow += "
"+ lang.video_conference_window_width +":
"; configWindow += "
"; if (getDbItem("userrole", "") == "superadmin") { configWindow += "
"+ lang.external_conf_users +"
"; configWindow += "
"; configWindow += ""; for (var cqt = 0; cqt < getDbItem("externalUserConfElem", ""); cqt++) { configWindow += ""; } configWindow += ""; configWindow += "
X
X
"; configWindow += ""; } configWindow += "

"; configWindow += "
"; configWindow += "
"; configWindow += ""; configWindow += "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"+ lang.notifications +":
"; configWindow += "
"; configWindow += "
"; configWindow += "
"; configWindow += "
"+ lang.email_integration +":
"; configWindow += "
"; configWindow += "
"+ lang.roundcube_domain +":
"; configWindow += "
"; configWindow += "
"+ lang.roundcube_user +":
"; configWindow += "
"; configWindow += "
"+ lang.roundcube_password +":
"; configWindow += "
"; configWindow += "
"+ lang.rc_basic_auth_user +":
"; configWindow += "
"; configWindow += "
"+ lang.rc_basic_auth_password +":
"; configWindow += "
"; configWindow += "

"; configWindow += "
"; configWindow += "
"+ lang.current_user_password +":
"; configWindow += "
"; configWindow += "
"+ lang.new_user_password +":
"; configWindow += "
"; configWindow += "
"+ lang.repeat_new_user_password +":
"; configWindow += "

"; configWindow += "
"; configWindow += "

"; configWindow += "
"; configWindow += "
"+ lang.current_user_email +":
"; configWindow += "
"; configWindow += "
"+ lang.new_user_email +":
"; configWindow += "
"; configWindow += "
"+ lang.repeat_new_user_email +":
"; configWindow += "

"; configWindow += "
"; configWindow += "

"; configWindow += "
"; configWindow += "
"+ lang.if_you_want_to_close_account +":


"; configWindow += "
"; configWindow += "

"; configWindow += "
"; var settingsSections = ""; settingsSections += ""; settingsSections += ""; settingsSections += ""; settingsSections += ""; settingsSections += ""; settingsSections += ""; settingsSections += ""; settingsSections += "
Connection Settings
Audio & Video
Profile Picture
Notifications
Email Integration
Change Password
Change Email
Close Account
"; $.jeegoopopup.open({ title: 'Settings', html: configWindow, width: '520', height: '500', center: true, scrolling: 'no', skinClass: 'jg_popup_basic', contentClass: 'configPopup', overlay: true, opacity: 50, draggable: true, resizable: false, fadeIn: 0 }); $("#jg_popup_b").append('
'); $("#jg_popup_l").append(settingsSections); if (getDbItem("useRoundcube", "") == 1) { $("#emailIntegration").prop("checked", true); } else { $("#emailIntegration").prop("checked", false); } $("#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 maxWidth = $(window).width() - 192; var maxHeight = $(window).height() - 98; if (maxWidth < 520 || maxHeight < 500) { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#maximizeImg").hide(); $("#minimizeImg").hide(); } else { $.jeegoopopup.width(520).height(500); $.jeegoopopup.center(); $("#minimizeImg").hide(); $("#maximizeImg").show(); } $(window).resize(function() { maxWidth = $(window).width() - 192; maxHeight = $(window).height() - 98; $.jeegoopopup.center(); if (maxWidth < 520 || maxHeight < 500) { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#maximizeImg").hide(); $("#minimizeImg").hide(); } else { $.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(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); }); // Output var selectAudioScr = $("#playbackSrc"); var playButton = $("#preview_output_play"); var playRingButton = $("#preview_ringer_play"); var pauseButton = $("#preview_output_pause"); // Microphone var selectMicScr = $("#microphoneSrc"); $("#Settings_AutoGainControl").prop("checked", AutoGainControl); $("#Settings_EchoCancellation").prop("checked", EchoCancellation); $("#Settings_NoiseSuppression").prop("checked", NoiseSuppression); // Webcam var selectVideoScr = $("#previewVideoSrc"); // Orientation var OrientationSel = $("input[name=Settings_Oriteation]"); OrientationSel.each(function(){ if(this.value == MirrorVideo) $(this).prop("checked", true); }); $("#local-video-preview").css("transform", MirrorVideo); // Frame Rate var frameRateSel = $("input[name=Settings_FrameRate]"); frameRateSel.each(function(){ if(this.value == maxFrameRate) $(this).prop("checked", true); }); // Quality var QualitySel = $("input[name=Settings_Quality]"); QualitySel.each(function(){ if(this.value == videoHeight) $(this).prop("checked", true); }); // Aspect Ratio var AspectRatioSel = $("input[name=Settings_AspectRatio]"); AspectRatioSel.each(function(){ if(this.value == videoAspectRatio) $(this).prop("checked", true); }); // Ring Tone var selectRingTone = $("#ringTone"); // Ring Device var selectRingDevice = $("#ringDevice"); // Handle Aspect Ratio Change AspectRatioSel.change(function(){ console.log("Call to change Aspect Ratio ("+ this.value +")"); var localVideo = $("#local-video-preview").get(0); localVideo.muted = true; localVideo.playsinline = true; localVideo.autoplay = true; var tracks = localVideo.srcObject.getTracks(); tracks.forEach(function(track) { track.stop(); }); var constraints = { audio: false, video: { deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" } } if($("input[name=Settings_FrameRate]:checked").val() != ""){ constraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val(); } if($("input[name=Settings_Quality]:checked").val() != ""){ constraints.video.height = $("input[name=Settings_Quality]:checked").val(); } if(this.value != ""){ constraints.video.aspectRatio = this.value; } console.log("Constraints:", constraints); var localStream = new MediaStream(); if(navigator.mediaDevices){ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ var videoTrack = newStream.getVideoTracks()[0]; localStream.addTrack(videoTrack); localVideo.srcObject = localStream; localVideo.onloadedmetadata = function(e) { localVideo.play(); } }).catch(function(e){ console.error(e); AlertConfigExtWindow(lang.alert_error_user_media, lang.error); }); } }); // Handle Video Height Change QualitySel.change(function(){ console.log("Call to change Video Height ("+ this.value +")"); var localVideo = $("#local-video-preview").get(0); localVideo.muted = true; localVideo.playsinline = true; localVideo.autoplay = true; var tracks = localVideo.srcObject.getTracks(); tracks.forEach(function(track) { track.stop(); }); var constraints = { audio: false, video: { deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" , } } if($("input[name=Settings_FrameRate]:checked").val() != ""){ constraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val(); } if(this.value){ constraints.video.height = this.value; } if($("input[name=Settings_AspectRatio]:checked").val() != ""){ constraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val(); } console.log("Constraints:", constraints); var localStream = new MediaStream(); if(navigator.mediaDevices){ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ var videoTrack = newStream.getVideoTracks()[0]; localStream.addTrack(videoTrack); localVideo.srcObject = localStream; localVideo.onloadedmetadata = function(e) { localVideo.play(); } }).catch(function(e){ console.error(e); AlertConfigExtWindow(lang.alert_error_user_media, lang.error); }); } }); // Handle Frame Rate Change frameRateSel.change(function(){ console.log("Call to change Frame Rate ("+ this.value +")"); var localVideo = $("#local-video-preview").get(0); localVideo.muted = true; localVideo.playsinline = true; localVideo.autoplay = true; var tracks = localVideo.srcObject.getTracks(); tracks.forEach(function(track) { track.stop(); }); var constraints = { audio: false, video: { deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" , } } if(this.value != ""){ constraints.video.frameRate = this.value; } if($("input[name=Settings_Quality]:checked").val() != ""){ constraints.video.height = $("input[name=Settings_Quality]:checked").val(); } if($("input[name=Settings_AspectRatio]:checked").val() != ""){ constraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val(); } console.log("Constraints:", constraints); var localStream = new MediaStream(); if(navigator.mediaDevices){ navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){ var videoTrack = newStream.getVideoTracks()[0]; localStream.addTrack(videoTrack); localVideo.srcObject = localStream; localVideo.onloadedmetadata = function(e) { localVideo.play(); } }).catch(function(e){ console.error(e); AlertConfigExtWindow(lang.alert_error_user_media, lang.error); }); } }); // Handle Audio Source changes (Microphone) selectMicScr.change(function(){ console.log("Call to change Microphone ("+ this.value +")"); // Change and update visual preview try{ var tracks = window.SettingsMicrophoneStream.getTracks(); tracks.forEach(function(track) { track.stop(); }); window.SettingsMicrophoneStream = null; } catch(e){} try{ soundMeter = window.SettingsMicrophoneSoundMeter; soundMeter.stop(); window.SettingsMicrophoneSoundMeter = null; } catch(e){} // Get Microphone var constraints = { audio: { deviceId: { exact: this.value } }, video: false } var localMicrophoneStream = new MediaStream(); navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream){ var audioTrack = mediaStream.getAudioTracks()[0]; if(audioTrack != null){ // Display Microphone Levels localMicrophoneStream.addTrack(audioTrack); window.SettingsMicrophoneStream = localMicrophoneStream; window.SettingsMicrophoneSoundMeter = MeterSettingsOutput(localMicrophoneStream, "Settings_MicrophoneOutput", "width", 50); } }).catch(function(e){ console.log("Failed to getUserMedia", e); }); }); // Handle output change (speaker) selectAudioScr.change(function(){ console.log("Call to change Speaker ("+ this.value +")"); var audioObj = window.SettingsOutputAudio; if(audioObj != null) { if (typeof audioObj.sinkId !== 'undefined') { audioObj.setSinkId(this.value).then(function() { console.log("sinkId applied to audioObj:", this.value); }).catch(function(e){ console.warn("Failed not apply setSinkId.", e); }); } } }); // Play button press playButton.click(function(){ try{ window.SettingsOutputAudio.pause(); } catch(e){} window.SettingsOutputAudio = null; try{ var tracks = window.SettingsOutputStream.getTracks(); tracks.forEach(function(track) { track.stop(); }); } catch(e){} window.SettingsOutputStream = null; try{ var soundMeter = window.SettingsOutputStreamMeter; soundMeter.stop(); } catch(e){} window.SettingsOutputStreamMeter = null; // Load Sample console.log("Audio:", audioBlobs.speaker_test.url); var audioObj = new Audio(audioBlobs.speaker_test.blob); audioObj.preload = "auto"; audioObj.onplay = function(){ var outputStream = new MediaStream(); if (typeof audioObj.captureStream !== 'undefined') { outputStream = audioObj.captureStream(); } else if (typeof audioObj.mozCaptureStream !== 'undefined') { return; } else if (typeof audioObj.webkitCaptureStream !== 'undefined') { outputStream = audioObj.webkitCaptureStream(); } else { console.warn("Cannot display Audio Levels") return; } // Display Speaker Levels window.SettingsOutputStream = outputStream; window.SettingsOutputStreamMeter = MeterSettingsOutput(outputStream, "Settings_SpeakerOutput", "width", 50); } audioObj.oncanplaythrough = function(e) { if (typeof audioObj.sinkId !== 'undefined') { audioObj.setSinkId(selectAudioScr.val()).then(function() { console.log("Set sinkId to:", selectAudioScr.val()); }).catch(function(e){ console.warn("Failed not apply setSinkId.", e); }); } // Play audioObj.play().then(function(){ // Audio Is Playing }).catch(function(e){ console.warn("Unable to play audio file", e); }); console.log("Playing sample audio file... "); } window.SettingsOutputAudio = audioObj; }); // Pause button press pauseButton.click(function() { if (window.SettingsOutputAudio.paused) { window.SettingsOutputAudio.play(); } else { window.SettingsOutputAudio.pause(); } }); playRingButton.click(function(){ try{ window.SettingsRingerAudio.pause(); } catch(e){} window.SettingsRingerAudio = null; try{ var tracks = window.SettingsRingerStream.getTracks(); tracks.forEach(function(track) { track.stop(); }); } catch(e){} window.SettingsRingerStream = null; try{ var soundMeter = window.SettingsRingerStreamMeter; soundMeter.stop(); } catch(e){} window.SettingsRingerStreamMeter = null; // Load Sample console.log("Audio:", audioBlobs.Ringtone.url); var audioObj = new Audio(audioBlobs.Ringtone.blob); audioObj.preload = "auto"; audioObj.onplay = function(){ var outputStream = new MediaStream(); if (typeof audioObj.captureStream !== 'undefined') { outputStream = audioObj.captureStream(); } else if (typeof audioObj.mozCaptureStream !== 'undefined') { return; // BUG: mozCaptureStream() in Firefox does not work the same way as captureStream() // the actual sound does not play out to the speakers... its as if the mozCaptureStream // removes the stream from the