PageSourceSearch

https://findmyspherecard.com/digital-business-card/themes/base/sdk/jss/app.js

js findmyspherecard.com collected 2026-10-02 00:29:46 UTC 95,267 bytes, 2,340 lines download raw bytes

1$(function () {
2    var sounds = {
3        'call': 'callingSignal',
4        'end': 'endCallSignal',
5        'rington': 'ringtoneSignal'
6    };
7    console.debug("App.js file loaded")
8    var initiatorID = "";
9    var ug = null;
10    var recorder = null;
11    var recorderTimeoutID;
12    var rejectcall = "";
13    var recorderOpts = {
14        onstart: function onStartRecord() {
15            $('.j-record').addClass('active');
16            recorderTimeoutID = setTimeout(function () {
17                if (recorder) {
18                    recorder.stop();
19                }
20            }, 600000); // 10min
21        },
22        onstop: function (blob) {
23            $('.j-record').removeClass('active');
24            var down = confirm('Do you want to download video?');
25            if (down) {
26                recorder.download('QB_WEBrtc_sample' + Date.now(), blob);
27            }
28            recorder = null;
29            clearTimeout(recorderTimeoutID);
30        },
31        onerror: function (error) {
32            console.error('Recorder error', error);
33        }
34    };
35    var isAudio = false;
36    // console.debug('appp',app);
37    var ui = {
38        'income_call': '#income_call',
39        'filterSelect': '.j-filter',
40        'videoSourceFilter': '.j-video_source',
41        'audioSourceFilter': '.j-audio_source',
42        'bandwidthSelect': '.j-bandwidth',
43        'insertOccupants': function (empty = true) {
44            var $occupantsCont = $('.j-users');
45            function cb($cont, res, empty) {
46                if (empty) {
47                    $cont.empty();
48                }
49                $cont.append(res).removeClass('wait');
50            }
51            return new Promise(function (resolve, reject) {
52                $occupantsCont.addClass('wait');
53                app.helpers.renderUsers().then(function (res) {
54                    cb($occupantsCont, res.usersHTML, empty);
55                    resolve(res.users);
56                }, function (error) {
57                    if (empty) {
58                        cb($occupantsCont, error.message, empty);
59                    } else {
60                        $occupantsCont.removeClass('wait');
61                        app.helpers.renderUsers.stop = true;
62                    }
63                    reject('Not found users');
64                });
65            });
66        }
67    };
68    var call = {
69        callTime: 0,
70        callTimer: null,
71        updTimer: function () {
72            this.callTime += 1000;
73            $('#timer').removeClass('invisible').text(new Date(this.callTime).toUTCString().split(/ /)[4]);
74        }
75    };
76    var remoteStreamCounter = 0;
77    var Router = Backbone.Router.extend({
78        'routes': {
79            'join': 'join',
80            'dashboard': 'dashboard',
81            '*query': 'relocated'
82        },
83        'container': $('.page'),
84        'relocated': function () {
85            var path = app.caller ? 'dashboard' : 'join';
86            app.router.navigate(path, { 'trigger': true });
87        },
88        'join': function () {
89            /** Before use WebRTC checking WebRTC is avaible */
90            if (!QB.webrtc) {
91                alert('Error: WebRTC is not available in your browser');
92                return;
93            }
94            if (!_.isEmpty(app.caller)) {
95                app.router.navigate('dashboard');
96                return false;
97            }
98            this.container.removeClass('page-dashboard').addClass('page-join');
99
100            /* app.helpers.setFooterPosition();*/
101            app.caller = {};
102            app.callees = {};
103            app.calleesAnwered = [];
104            app.calleesRejected = [];
105            app.users = [];
106            app.callees_group = {};
107            var user = JSON.parse(localStorage.getItem('data'));
108            if (user) {
109                $('.j-join__username').val(user.username);
110            }
111        },
112        'dashboard': function () {
113            if (_.isEmpty(app.caller)) {
114                app.router.navigate('join', { 'trigger': true });
115                return false;
116            }
117            $(".preload").fadeOut(function () {
118                $('html, body').css({
119                    'overflow': 'auto',
120                    'height': '100%'
121                });
122            });
123
124            /** render page */
125            this.container.removeClass('page-join').addClass('page-dashboard').find('.j-dashboard').empty();
126
127            /** render skelet */
128            $('.j-dashboard').append($('#dashboard_tpl').html());
129
130            /** render stateBoard */
131            app.helpers.stateBoard = new app.helpers.StateBoard('.j-state_board', {
132                title: 'tpl_default',
133                property: {
134                    'name': app.caller.full_name,
135                }
136            });
137
138            /** render users wrapper */
139            $('.j-users_wrap').append($('#users_tpl').html());
140            ui.insertOccupants().then(function (users) {
141                app.users = users;
142            }, function (err) {
143                console.warn(err);
144            }
145            );
146
147            /** render frames */
148            var framesTpl = _.template($('#frames_tpl').html());
149            $('.j-board').append(framesTpl({ 'nameUser': app.caller.full_name }));
150
151            // Hide a record button if browser not supported it
152            if (!QBMediaRecorder.isAvailable()) {
153                $('.j-record').hide();
154            }
155            fillMediaSelects();
156
157            /*app.helpers.setFooterPosition();*/
158        }
159    });
160
161
162    /**
163    * INIT
164    */
165
166    /** Test server / app by defaults */
167    const creds = {
168        //'appId': '89340',
169        //'authKey': 'S7FcCn6BbyeAFd8',
170        //'authSecret': '8N7GYrOZp7B8nyC',
171        //'accountKey': 'pksxk1_4Hj-P7BHqwsRs'
172        'appId': '100853',
173        'authKey': 'bKuHCREdwm2x8Tg',
174        'authSecret': 'WLnP7hAnLVHp9pG',
175        'accountKey': 'koSysSANXcEr-TZ_pgh-'
176    };
177
178    const config = {
179        // debug: { mode: 1 },
180        debug: false,
181        webrtc: {
182            answerTimeInterval: 60,
183            dialingTimeInterval: 5,
184            disconnectTimeInterval: 35,
185            statsReportTimeInterval: 5
186        }
187    };
188    CRED = {
189        'CREDENTIALS': creds,
190        'APP_CONFIG': config
191    };
192    QB.init(
193        CRED.CREDENTIALS.appId,
194        CRED.CREDENTIALS.authKey,
195        CRED.CREDENTIALS.authSecret,
196        CRED.CREDENTIALS.accountKey,
197        CRED.APP_CONFIG
198    );
199
200    //        /* Insert version + versionBuild to sample for QA */
201    //        $('.j-version').text('v.' + QB.version + '.' + QB.buildNumber);
202    //        /* Insert info about creds and endpoints */
203    //        let configTxt = 'Uses: ' + JSON.stringify(CONFIG.CREDENTIALS) + ',';
204    //        configTxt += ' endpoints: ' + (CONFIG.APP_CONFIG.endpoints ? JSON.stringify(CONFIG.APP_CONFIG.endpoints) : 'test server');
205    //        $('.j-config').text(configTxt);
206    var statesPeerConn = _.invert(QB.webrtc.PeerConnectionState);
207    app.router = new Router();
208
209
210    Backbone.history.start();
211    $(document).on('input', '#search_by_username', function (e) {
212        var userName = e.target.value.trim();
213        var isValid = 25 >= userName.length;
214        if (!isValid) {
215            return false;
216        }
217        app.callees = {};
218        app.helpers.renderUsers.stop = false;
219        app.helpers.renderUsers.condition = {
220            order: {
221                field: "updated_at",
222                sort: "desc"
223            },
224            page: 1,
225            per_page: 100
226        };
227        if (userName.length >= 1) {
228            app.helpers.renderUsers.condition.filter = {
229                field: 'full_name',
230                param: 'in',
231                value: [userName]
232            };
233        }
234        ui.insertOccupants().then(function (users) {
235            app.users = users;
236            /*app.helpers.setFooterPosition();*/
237        }, function () {
238            /*app.helpers.setFooterPosition();*/
239        });
240    });
241
242    $(window).scroll(function () {
243        if (($(window).scrollTop() == $(document).height() - $(window).height()) && app.helpers.renderUsers.condition.page != undefined && !app.helpers.renderUsers.stop) {
244            app.helpers.renderUsers.condition.page += 1;
245            ui.insertOccupants(false).then(function (users) {
246                var ids = users.map(function (user) {
247                    return user.id;
248                });
249                app.users = users.concat(app.users.filter(function (item) {
250                    return ids.indexOf(item.id) < 0;
251                }));
252
253                /*app.helpers.setFooterPosition();*/
254            }, function () {
255                /* app.helpers.setFooterPosition();*/
256            });
257        }
258    });
259
260    /**
261     * JOIN
262    */
263    $(document).on('click', '.j-join', function () {
264        /*alert(localStorage.getItem('name2').split('@')[0]);*/
265        var data = {
266            username: localStorage.getItem('name1'),
267            email: localStorage.getItem('name3'),
268            login: localStorage.getItem('name2'),
269            custom_data: localStorage.getItem('custom_data'),
270            token: localStorage.getItem('QB-Token')
271        }
272        // console.log('[get-consol]',data.custom_data);
273        /*  data = _.object( _.map(form.serializeArray(), function(item) {
274                return [item.name, item.value.trim()];
275        }));*/
276        localStorage.setItem('data', JSON.stringify(data));
277        localStorage.removeItem('name1');
278        localStorage.removeItem('name2');
279        localStorage.removeItem('name3');
280        localStorage.removeItem('custom_data');
281
282        /** Check internet connection */
283        if (!window.navigator.onLine) {
284            alert("Please check your Internet connection and try again");
285            return false;
286        }
287        if (localStorage.getItem('isAuth')) {
288            /*  $('#already_auth').modal();*/
289            app.router.navigate('dashboard', { trigger: true });
290            /*return false;*/
291        }
292
293        $("#form").addClass('join-wait');
294        // var url = "https://api.quickblox.com/session.json";
295        // var xhr = new XMLHttpRequest();
296        // xhr.open("GET", url);
297        // xhr.setRequestHeader("Content-Type", "application/json");
298        // xhr.setRequestHeader("QB-Token",""); // data.token
299        // xhr.onreadystatechange = function () {
300
301        //     if (xhr.readyState === 4) {
302        //         // console.log(xhr.status);
303        //         // console.log(xhr.responseText);
304        //         obj = JSON.parse(xhr.responseText);
305
306        //         //console.log(obj);
307        //         // console.log('[response-token]',obj);
308        //         /*alert(obj['session'].token); */   
309        //         if(obj['session']){
310        //              alert(obj);
311        //             app.caller = obj['session'];
312        //             QB.chat.connect({
313        //                 jid: QB.chat.helpers.getUserJid( app.caller.user_id, CRED.CREDENTIALS.appId ),
314        //                 password: btoa('quickblox@chat#chat$findmyspherecard')
315        //             }, function(err, res) {
316        //                 if(err) {
317        //                     if(!_.isEmpty(app.currentSession)) {
318        //                         app.currentSession.stop({});
319        //                         app.currentSession = {};
320        //                     }
321        //                     app.helpers.changeFilter('#localVideo', 'no');
322        //                     app.helpers.changeFilter('#main_video', 'no');
323        //                     app.mainVideo = 0;
324        //                     $(ui.filterSelect).val('no');
325        //                     app.calleesAnwered = [];
326        //                     app.calleesRejected = [];
327        //                     if(call.callTimer) {
328        //                         $('#timer').addClass('invisible');
329        //                         clearInterval(call.callTimer);
330        //                         call.callTimer = null;
331        //                         call.callTime = 0;
332        //                         app.helpers.network = {};
333        //                     }
334        //                 } else {
335        //                   //  console.log('[jid-res]',res);
336        //                     app.helpers.renderUsers();
337        //                     $("#form").removeClass('join-wait');
338        //                     $("#form").trigger('reset');
339        //                     localStorage.setItem('isAuth', true);
340        //                     app.router.navigate('dashboard', { trigger: true });
341        //                 }
342        //             });
343        //         }else{
344        //  alert('test1');
345        app.helpers.join(data).then(function (user) {
346
347            //console.log('[helpers-return]',user);
348            app.caller = user;
349            //alert("2==" + color);
350            QB.chat.connect({
351                jid: QB.chat.helpers.getUserJid(app.caller.id, CRED.CREDENTIALS.appId),
352                password: btoa('quickblox@chat#chat$findmyspherecard')
353            }, function (err, res) {
354                if (err) {
355                    if (!_.isEmpty(app.currentSession)) {
356                        app.currentSession.stop({});
357                        app.currentSession = {};
358                    }
359                    app.helpers.changeFilter('#localVideo', 'no');
360                    app.helpers.changeFilter('#main_video', 'no');
361                    app.mainVideo = 0;
362                    $(ui.filterSelect).val('no');
363                    app.calleesAnwered = [];
364                    app.calleesRejected = [];
365                    if (call.callTimer) {
366                        $('#timer').addClass('invisible');
367                        clearInterval(call.callTimer);
368                        call.callTimer = null;
369                        call.callTime = 0;
370                        app.helpers.network = {};
371                    }
372                } else {
373                    $("#form").removeClass('join-wait');
374                    $("#form").trigger('reset');
375                    localStorage.setItem('isAuth', true);
376                    app.router.navigate('dashboard', { trigger: true });
377                    /* alert($("#userListContainer .chat_list").attr("data-name"));*/
378                    //$('.page').removeClass('page-join');
379                    // $('.page').addClass('page-dashboard')
380                    // $('.page').find('.j-dashboard').empty();
381                    /** render skelet */
382                    //$('.j-dashboard').append( $('#dashboard_tpl').html() );
383                    // $('.j-users_wrap').append( $('#users_tpl').html() );
384                    //var framesTpl = _.template( $('#frames_tpl').html() );
385                    //$('.j-board').append( framesTpl({'nameUser': app.caller.full_name}));
386                }
387            });
388        }).catch(function (error) {
389            $("#form").removeClass('join-wait');
390            try {
391                if (typeof error.message == "string") {
392                    $('#join_err').find('.error', 0).text(error.message);
393                } else {
394                    $('#join_err').find('.error', 0).text(error.message.errors.base[0]);
395                }
396            } catch (e) {
397                //   console.log(error);
398            }
399            $('#join_err').modal();
400        });
401        // }
402        //}
403
404        // };
405        // xhr.send();   
406        // return false;
407    });
408
409    /**
410     * DASHBOARD
411     */
412    /** REFRESH USERS */
413    $(document).on('click', '.j-users__refresh', function () {
414        var $btn = $(this);
415        app.callees = {};
416        $btn.prop('disabled', true);
417        app.helpers.renderUsers.stop = false;
418        app.helpers.renderUsers.condition.page = 1;
419        ui.insertOccupants().then(function (users) {
420            app.users = users;
421
422            $btn.prop('disabled', false);
423            /*app.helpers.setFooterPosition();*/
424        }, function () {
425            $btn.prop('disabled', false);
426            /*app.helpers.setFooterPosition();*/
427        });
428    });
429
430    /** Check / uncheck user (callee) */
431
432
433    // Function to convert QB.users.get to a Promise
434    function getUserDetails(email) {
435        return new Promise((resolve, reject) => {
436            window.QB.users.get({ email }, function (error, user) {
437                if (error) {
438                    reject(error);
439                } else {
440                    resolve(user);
441                }
442            });
443        });
444    }
445
446    $(".chat_list").click(function (e) {
447        let cid = $(this).attr("data-cid");
448        sessionStorage.setItem("app_callees", JSON.stringify({ [cid]: cid }))
449    })
450
451
452
453
454    $(".j-user").click(async function (e) {
455        e.stopPropagation();
456        e.preventDefault();
457        app.callees = {};
458        /* var $user = $(this),*/
459        var cid = undefined;
460        var cname = undefined;
461        var user = undefined;
462        cid = $("#namevalue").attr('data-id');
463        cname = $("#namevalue").attr('data-name');
464        //console.log(cname);
465
466
467        if (!cid) {
468            try {
469                // Use await to get user details
470                const user = await getUserDetails($.trim(cname));
471                $("#namevalue").data('id', user.id); // Cache the ID in the DOM
472                cid = user.id; // Update `cid` with the fetched user ID
473                sessionStorage.setItem('user-data-cid', JSON.stringify(cid));
474            } catch (error) {
475                // alert('Error fetching user:', error);
476                return; // Exit if there's an error
477            }
478        }
479
480        user = {
481            id: +$.trim(cid),
482            name: $.trim(cname),
483        };
484        app.callees[user.id] = user.id;
485        sessionStorage.setItem('app_callees', JSON.stringify(app.callees));
486        if ($("#namevalue").hasClass('active')) {
487            /* delete app.callees[user.id];
488            $user.removeClass('active');*/
489            app.callees[user.id] = user.id;
490            ug = user.name;
491            //  console.log('[user-1]',app.callees[user.id]);
492        } else {
493            app.callees[user.id] = user.id;
494            $("#namevalue").addClass('active');
495            // console.log('[user-2]',app.callees[user.id]);
496            ug = user.name;
497        }
498    });
499
500    $(document).on('click', '.j-callee', async function (e) {
501        e.preventDefault();
502        // app.callees ={};
503        /* var $user = $(this),*/
504        const cid = $.trim($(this).attr('data-cid'))
505        user = {
506            id: +$.trim($(this).attr('data-cid')),
507            name: $.trim($(this).attr('data-email'))
508        };
509
510
511
512        // $("#user_list").click(function (e) {
513        //     console.debug('jdksfa', $(this).attr('data-cid'));
514        //     let group_cid = $(this).attr("data-email");  
515        //     console.debug('jdksfa', group_cid);
516        // })
517
518        if (!cid) {
519            const userData = await getUserDetails($.trim($(this).attr('data-email')));
520            user.id = userData.id;
521            $(this).attr('data-cid', userData.id);
522            $(this).addClass('cid');
523            app.callees_group[user.id] = user.id;
524        }
525        if ($(this).hasClass('g_active')) {
526            /* delete app.callees[user.id];
527            $user.removeClass('active');*/
528            $(this).removeClass('g_active');
529            // app.callees_group={};
530            ug = user.name;
531            delete app.callees_group[$(this).attr('data-cid')];
532            // console.log('[user-1]',app.callees_group);
533        } else {
534            app.callees_group[user.id] = user.id;
535            $(this).addClass('g_active');
536            ug = user.name;
537            $(".person_type_g").removeClass("hide");
538        }
539        //   console.log('[user-detail]',user);
540        // if (!$(this).hasClass('cid')) {
541        //     $(this).removeClass('g_active');
542        // } else {
543        //     if ($(this).hasClass('g_active')) {
544        //         /* delete app.callees[user.id];
545        //         $user.removeClass('active');*/
546        //         $(this).removeClass('g_active');
547        //         // app.callees_group={};
548        //         ug = user.name;
549        //         delete app.callees_group[$(this).attr('data-cid')];
550        //         // console.log('[user-1]',app.callees_group);
551        //     } else {
552        //         app.callees_group[user.id] = user.id;
553        //         $(this).addClass('g_active');
554        //         ug = user.name;
555        //         $(".person_type_g").removeClass("hide");
556        //     }
557
558        // }
559        var count = Object.keys(app.callees_group).length;
560        if (count >= 5) {
561            alert("Select call MIN: 2 | MAX: 4");
562            $(this).removeClass('g_active');
563            ug = user.name;
564            delete app.callees_group[$(this).attr('data-cid')];
565        } else {
566            // if (count == 1) {
567            //     $('.j-callee').addClass('hide');
568            // }
569            // else {
570            $('.j-callee').removeClass('hide');
571            // }
572
573        }
574        //console.log('[user-2]>>>>>>',app.callees_group);
575    });
576
577    function sendPushNotification() {
578        // and also send push notification about incoming call
579        // (currently only iOS/Android users will receive it)
580        var users = [app.caller].concat(app.users);
581
582        var opponentsIDsNumbers = app.currentSession
583            .opponentsIDs
584            .map(Number);
585        var opponentsIDs = [app.currentSession.initiatorID].concat(opponentsIDsNumbers);
586        var contactIdentifier = opponentsIDs
587            .map(function (userId) {
588                var user = users.find(function (usr) {
589                    return usr.id === userId
590                });
591                return user ? user.full_name : undefined;
592            })
593            .filter(Boolean)
594            .join();
595
596        console.log('sending opponentsIDs', opponentsIDs);
597        var pushPayload = {
598            message: app.caller.full_name + " is calling you",
599            ios_voip: 1,
600            VOIPCall: 1,
601            sessionID: app.currentSession.ID,
602            opponentsIDs: opponentsIDs.join(),
603            contactIdentifier: contactIdentifier,
604            conferenceType: app.currentSession.callType.toString(),
605            timestamp: Date.now().toString()
606        };
607        console.debug('Group opponentsIDs', opponentsIDs);
608        console.debug('Group opponentsIDsNumbers', opponentsIDsNumbers);
609        var params = {
610            notification_type: 'push',
611            user: { ids: opponentsIDsNumbers.map((id) => parseInt(id)) },
612            environment: "production", // environment, can be 'production' as well.
613            message: QB.pushnotifications.base64Encode(
614                JSON.stringify(pushPayload)
615            )
616        };
617        $("#notify").text("initiate call");
618        //
619        QB.pushnotifications.events.create(params, function (error) {
620            if (error) {
621                console.log(error);
622            } else {
623                // success
624                console.log("Push Notification is sent.");
625            }
626        });
627    }
628
629    /** Call / End of call */
630    $(document).on('click', '.j-actions_group', function () {
631        $(".person_type_g").removeClass("hide");
632        $('#user_group_call').modal('hide');
633
634        var $btn = $(this),
635            $videoSourceFilter = $(ui.videoSourceFilter),
636            $audioSourceFilter = $(ui.audioSourceFilter),
637
638
639            $bandwidthSelect = $(ui.bandwidthSelect),
640            bandwidth = $.trim($(ui.bandwidthSelect).val()),
641            videoElems = '',
642            mediaParams = {
643                'audio': {
644                    deviceId: $audioSourceFilter.val() ? $audioSourceFilter.val() : undefined
645                },
646                'video': {
647                    deviceId: $videoSourceFilter.val() ? { exact: $videoSourceFilter.val() } : undefined
648                },
649                'options': {
650                    'muted': true,
651                    'mirror': true
652                },
653                'elemId': 'localVideo'
654            };
655        /* Hangup */
656        if ($btn.hasClass('hangup')) {
657            if (!_.isEmpty(app.currentSession)) {
658
659                if (recorder && recorderTimeoutID) {
660                    recorder.stop();
661
662                }
663
664                app.currentSession.stop({});
665                app.currentSession = {};
666
667                app.helpers.stateBoard.update({
668                    'title': 'tpl_default',
669                    'property': {
670                        'name': app.caller.full_name,
671                    }
672                });
673
674                app.helpers.setFooterPosition();
675
676                return false;
677            }
678        } else {
679            /** Check internet connection */
680            if (!window.navigator.onLine) {
681                app.helpers.stateBoard.update({ 'title': 'no_internet', 'isError': 'qb-error' });
682                return false;
683            }
684            /** Check callee */
685            if (_.isEmpty(app.callees_group)) {
686                // console.debug("app.callees_group___", app.callees_group);
687                $('#error_no_calles').modal();
688                return false;
689            }
690
691
692            app.helpers.stateBoard.update({ 'title': 'create_session' });
693
694            isAudio = $btn.data('call') === 'audio';
695
696
697
698            if (isAudio) {
699                mediaParams = {
700                    audio: true,
701                    video: false
702                };
703
704                var img_type = $("#userListContainer li").attr("data-email", ug).data("profile");
705                // var img_type = $("#profileUserImage").val();
706
707                /* alert("==="+img_type);*/
708                var local = $("#local-img").attr("src");
709                /*alert("=="+local);*/
710                $('#main_video').css('background-image', 'url(' + img_type + ')');
711                $('#main_video').css('background-repeat', 'no-repeat');
712                $('#main_video').css('background-size', 'cover');
713                $('#main_video').css('background-position', 'center top');
714
715                $('#localVideo').css('background-image', 'url(' + local + ')');
716                $('#localVideo').css('background-size', 'cover');
717                $('#localVideo').css('background-position', 'center top');
718
719                $('.m-audio_call').addClass('hangup');
720                $('#model_call').trigger('click');
721                document.querySelector('.j-actions[data-call="video"]').setAttribute('hidden', true);
722            } else {
723
724                var local = $("#local-img").attr("src");
725
726                $('#localVideo').css('background-image', 'url(' + local + ')');
727                $('#localVideo').css('background-size', 'cover');
728                $('#localVideo').css('background-position', 'center top');
729
730                $('#model_call').trigger('click');
731                $('.m-video_call').addClass('hangup');
732                document.querySelector('.j-actions[data-call="audio"]').setAttribute('hidden', true);
733            }
734
735
736
737
738            const callees_group = Object.keys(app.callees_group).filter((id) => ![undefined, "undefined", "", null].includes(id)).map((id) => parseInt(id))
739            console?.debug("Group Calles Group ", callees_group)
740            app.currentSession = QB.webrtc.createNewSession(callees_group, isAudio ? QB.webrtc.CallType.AUDIO : QB.webrtc.CallType.VIDEO, null, { 'bandwidth': bandwidth });
741
742
743            app.currentSession.getUserMedia(mediaParams, function (err, stream) {
744                if (err || !stream.getAudioTracks().length || (isAudio ? false : !stream.getVideoTracks().length)) {
745                    console.debug("getUserMedia ERROR", err)
746                    app.currentSession.stop({});
747                    app.helpers.stateBoard.update({
748                        'title': 'tpl_device_not_found',
749                        'isError': 'qb-error',
750                        'property': {
751                            'name': app.caller.full_name
752                        }
753                    });
754                } else {
755                    app.helpers.stateBoard.update({
756                        'title': 'p2p_call_stop',
757                        'property': {
758                            'name': "ssss",
759                            'currentName': "sssss",
760                            'reason': 'not answered'
761                        }
762                    });
763                    // Call to users
764                    app.currentSession.call({}, function () {
765                        if (!window.navigator.onLine) {
766                            app.currentSession.stop({});
767                            app.helpers.stateBoard.update({ 'title': 'connect_error', 'isError': 'qb-error' });
768                        } else {
769                            var compiled = _.template($('#callee_video').html());
770
771                            app.helpers.stateBoard.update({ 'title': 'calling' });
772                            Object.keys(app.callees_group).forEac
772h(function (id) {
773                                videoElems += compiled({
774                                    'userID': id,
775                                    'name': app.callees_group[id],
776                                    'state': 'connecting'
777                                    // 'profile': app.users[i].custom_data,
778                                });
779                            });
780
781                            sendPushNotification();
782
783                            $('.j-callees').append(videoElems);
784
785                            $bandwidthSelect.attr('disabled', true);
786                            $btn.addClass('hangup');
787                            // app.helpers.setFooterPosition();
788                        }
789                    });
790                }
791            });
792        }
793    });
794
795    $(document).on("click", "#localVideo", function () {
796        $("#main_video").addClass("small-video-display")
797        $(this).parent().parent().addClass("large-video-display")
798    });
799
800    $(document).on("click", "#main_video", function () {
801        $("#localVideo").parent().parent().removeClass("large-video-display")
802        $(this).removeClass("small-video-display")
803    });
804
805
806    /** Call / End of call */
807
808
809    $(document).on('click', '.j-actions', function () {
810        $('#user_group_call').modal('hide');
811        $(".person_type_g").addClass("hide");
812        $('.j-fullscreen').addClass("hide");
813        $('.j-caller__ctrl[data-target="screen"]').addClass("hide");
814        app.callees_group = {};
815        var $btn = $(this),
816            $videoSourceFilter = $(ui.videoSourceFilter),
817            $audioSourceFilter = $(ui.audioSourceFilter),
818            $bandwidthSelect = $(ui.bandwidthSelect),
819            bandwidth = $.trim($(ui.bandwidthSelect).val()),
820            videoElems = '',
821            mediaParams = {
822                'audio': {
823                    deviceId: $audioSourceFilter.val() ? $audioSourceFilter.val() : undefined
824                },
825                'video': {
826                    deviceId: $videoSourceFilter.val() ? { exact: $videoSourceFilter.val() } : undefined
827                },
828                'options': {
829                    'muted': true,
830                    'mirror': true
831                },
832                'elemId': 'localVideo'
833            };
834        /** Hangup */
835        if ($btn.hasClass('hangup')) {
836
837            /*alert("hangup-1");*/
838
839            var url = window.location.origin + '/call/hangup-call';
840            $.ajax({
841                url: url,
842                type: 'POST',
843                dataType: 'json',
844                data: {
845                    'user_id': app.caller['id'],
846                    'call_time': new Date(),
847                    'rtc_id': app.currentSession.ID,
848                    'status': 'accept',
849                },
850                contentType: 'application/x-www-form-urlencoded;charset=ISO-8859-15',
851                async: false,
852                success: function (response) {
853                    console.log('success');
854                },
855                error: function (request, error) {
856                    console.log(error);
857                }
858            });
859            if (!_.isEmpty(app.currentSession)) {
860                if (recorder && recorderTimeoutID) {
861                    recorder.stop();
862                }
863                app.currentSession.stop({});
864                app.currentSession = {};
865                app.helpers.stateBoard.update({
866                    'title': 'tpl_default',
867                    'property': {
868                        'name': app.caller.full_name,
869                    }
870                });
871                /*app.helpers.setFooterPosition();*/
872                return false;
873            }
874
875        } else {
876            /** Check internet connection */
877            if (!window.navigator.onLine) {
878                app.helpers.stateBoard.update({ 'title': 'no_internet', 'isError': 'qb-error' });
879                return false;
880            }
881
882            let callies = app.callees
883
884            if (sessionStorage.getItem("app_callees")) {
885                callies = JSON.parse(sessionStorage.getItem("app_callees"));
886            }
887
888
889            // app.callees = sessionStorage.getItem('app_callees') ? JSON.parse(sessionStorage.getItem('app_callees')) : {};
890            // console.debug('callees_____', app.callees);
891            if (_.isEmpty(callies)) {
892                // alert('check caller');
893                // $('#error_no_calles').modal();
894                return false;
895            }
896
897
898            /** Check callee */
899
900
901
902            app.helpers.stateBoard.update({ 'title': 'create_session' });
903            isAudio = $btn.data('call') === 'audio';
904
905            app.currentSession = QB.webrtc.createNewSession(Object.keys(callies).map((id) => parseInt(id)), isAudio ? QB.webrtc.CallType.AUDIO : QB.webrtc.CallType.VIDEO, null, { 'bandwidth': bandwidth });
906
907
908
909
910
911            if (isAudio) {
912
913                mediaParams = {
914                    audio: true,
915                    video: false
916                };
917
918                var img_type = $("#profileUserImage").val();
919                var local = $("#local-img").attr("src");
920
921                $('#main_video').css('background-image', 'url(' + img_type + ')');
922                $('#main_video').css('background-repeat', 'no-repeat');
923                $('#main_video').css('background-size', 'cover');
924                //$('#main_video').css('background-position', 'center top');
925                $('#main_video').css('width', '200px');
926                $('#main_video').css('height', '200px');
927                $('#main_video').css('border-radius', '50%');
928                $('#main_video').css('background-position', 'center');
929
930                $('#localVideo').css('background-image', 'url(' + local + ')');
931                $('#localVideo').css('background-size', 'cover');
932                $('#localVideo').css('background-position', 'center top');
933
934                $('.m-audio_call').addClass('hangup');
935                //$('#model_call').trigger('click');
936                $("#myModalAV").modal('show');
937                document.querySelector('.j-actions[data-call="video"]').setAttribute('hidden', true);
938
939            } else {
940
941                var img_type = $("#profileUserImage").val();
942                var local = $("#local-img").attr("src");
943
944                $('#main_video').css('background-image', 'url(' + img_type + ')');
945                $('#main_video').css('background-repeat', 'no-repeat');
946                $('#main_video').css('background-size', 'cover');
947                //$('#main_video').css('background-position', 'center top');
948                $('#main_video').css('width', '200px');
949                $('#main_video').css('height', '200px');
950                $('#main_video').css('border-radius', '50%');
951                $('#main_video').css('background-position', 'center');
952
953                $('#localVideo').css('background-image', 'url(' + local + ')');
954                $('#localVideo').css('background-size', 'cover');
955                $('#localVideo').css('background-position', 'center top');
956
957                // $('#model_call').trigger('click');
958                $("#myModalAV").modal('show');
959                $('.m-video_call').addClass('hangup');
960
961                document.querySelector('.j-actions[data-call="audio"]').setAttribute('hidden', true);
962            }
963
964
965            
966            if (app.currentSession.opponentsIDs.length == 1) {
967                $(".caller__frames").css({
968                    width: "15%",
969                    height: "auto",
970                    "border-top": "none",
971                    "border-right": "none",
972                    "border-bottom": "0px",
973                    "border-left": "none",
974                    "border-image": "initial",
975                    position: "absolute",
976                    bottom: "0px",
977                    right: "0px",
978                    padding: "0px",
979                    "border-radius": "6px 6px 0px 0px",
980                    overflow: "hidden",
981                    background: "#777777",
982    
983                })
984            }
985            app.currentSession.getUserMedia(mediaParams, function (err, stream) {
986
987                if (err || !stream.getAudioTracks().length || (isAudio ? false : !stream.getVideoTracks().length)) {
988                    // console.log(stream.getAudioTracks().length);
989                    alert("Please allow Camera and Mic");
990                    var errorMsg = '';
991                    app.currentSession.stop({});
992                    app.helpers.stateBoard.update({
993                        'title': 'tpl_device_not_found',
994                        'isError': 'qb-error',
995                        'property': {
996                            'name': app.caller.full_name
997                        }
998                    });
999                } else {
1000                    var callParameters = {};
1001                    if (isAudio) {
1002                        callParameters.callType = 2;
1003                    }
1004
1005                    // Call to users
1006                    var pushRecipients = [];
1007                    var CurrUserID = app.currentSession.currentUserID;
1008                    pushRecipients.push(CurrUserID);
1009                    app.currentSession.call({}, function () {
1010                        if (!window.navigator.onLine) {
1011                            app.currentSession.stop({
1012
1013                            });
1014                            app.helpers.stateBoard.update({ 'title': 'connect_error', 'isError': 'qb-error' });
1015                        } else {
1016                            var compiled = _.template($('#callee_video').html());
1017                            app.helpers.stateBoard.update({ 'title': 'calling' });
1018                            document.getElementById(sounds.call).play();
1019                            Object.keys(app.callees).forEach(function (id, i, arr) {
1020                                videoElems += compiled({
1021                                    'userID': id,
1022                                    'name': app.callees[id],
1023                                    'state': 'connecting'
1024                                });
1025                                pushRecipients.push(id);
1026                            });
1027
1028                            $('.j-callees').append(videoElems);
1029                            $bandwidthSelect.attr('disabled', true);
1030                            $btn.addClass('hangup');
1031                        }
1032                    });
1033                    if (pushRecipients) {
1034                        let this_user = String(app.caller['id']);
1035                        pushRecipients.splice(0, 0, this_user)
1036                        var users_id = pushRecipients;
1037                        let arr = [];
1038                        var i = 0;
1039                        let all_user = app.users;
1040                        all_user.forEach(user => {
1041                            if (users_id.indexOf(String(user['id'])) !== -1) {
1042                                arr.push([]);
1043                                arr[i] = user;
1044                                i++;
1045                            }
1046                        });
1047                        var call_type = isAudio === true ? 'audio' : 'video';
1048                        var baseUrl = '<?php echo \Yii::$app->request->baseUrl; ?>';
1049                        var url = baseUrl + '/call/save-call';
1050                        // var url = window.location.origin+'/call/save-call';
1051                        $.ajax({
1052                            url: url,
1053                            type: 'POST',
1054                            dataType: 'json',
1055                            data: {
1056                                'arr': arr,
1057                                'c_user': app.caller['id'],
1058                                'pushPayload': app.currentSession.ID,
1059                                'call_type': call_type
1060                            },
1061                            contentType: 'application/x-www-form-urlencoded;charset=ISO-8859-15',
1062                            async: false,
1063                            success: function (response) {
1064                                console.log('success');
1065                            },
1066                            error: function (request, error) {
1067                                console.log(error);
1068                            }
1069                        });
1070                    }
1071
1072                    // and also send push notification about incoming call
1073                    // (corrently only iOS/Android users will receive it)
1074                    var users = [app.caller].concat(app.users);
1075                    var opponentsIDsNumbers = app.currentSession.opponentsIDs.map(Number);
1076                    var opponentsIDs = [app.currentSession.initiatorID].concat(opponentsIDsNumbers);
1077                    var contactIdentifier = opponentsIDs.map(function (userId) {
1078                        var user = users.find(function (usr) {
1079                            return usr.id === userId
1080                        });
1081                        return user ? user.full_name : undefined;
1082                    }).filter(Boolean).join();
1083
1084                    // opponentsIDs=["138343544","139666851"]
1085                    // pushRecipients=["138343544","138394900"]
1086                    var pushPayload = {
1087                        message: app.caller.full_name + " is calling you",
1088                        ios_voip: "1",
1089                        VOIPCall: "1",
1090                        sessionID: app.currentSession.ID,
1091                        opponentsIDs: opponentsIDs.join(),
1092                        contactIdentifier: contactIdentifier,
1093                        conferenceType: app.currentSession.callType.toString(),
1094                        timestamp: Date.now().toString()
1095                    };
1096                    if (pushPayload) {
1097                        let opponentsIDs = pushPayload['opponentsIDs'].split(',');
1098                        let arr = [];
1099                        var i = 0;
1100                        let all_user = app.users;
1101                        all_user.forEach(user => {
1102                            if (opponentsIDs.indexOf(String(user['id'])) !== -1) {
1103                                arr.push([]);
1104                                arr[i] = user;
1105                                i++;
1106                            }
1107                        });
1108                        var call_type = isAudio == true ? 'audio' : 'video';
1109                        var baseUrl = '<?php echo \Yii::$app->request->baseUrl; ?>';
1110                        var url = baseUrl + '/call/save-call';
1111                        // var url = window.location.origin+'/call/save-call';
1112                        $.ajax({
1113                            url: url,
1114                            type: 'POST',
1115                            dataType: 'json',
1116                            data: {
1117                                'arr': arr,
1118                                'c_user': app.caller['id'],
1119                                'pushPayload': app.currentSession.ID,
1120                                'call_type': call_type,
1121                            },
1122                            contentType: 'application/x-www-form-urlencoded;charset=ISO-8859-15',
1123                            async: false,
1124                            success: function (response) {
1125                                console.log('success');
1126                            },
1127                            error: function (request, error) {
1128                                console.log(error);
1129                            }
1130                        });
1131                    }
1132                    var params = {
1133                        notification_type: 'push',
1134                        user: { ids: opponentsIDs.map((id) => parseInt(id)) },
1135                        environment: 'production', // environment, can be 'production' as well. development 
1136                        // message: QB.pushnotifications.base64Encode(JSON.stringify({
1137                        //     "message": "test is calling you",
1138                        //     "ios_voip": "1",
1139                        //     "VOIPCall": "1"
1140                        // }))
1141                        message: QB.pushnotifications.base64Encode(
1142                            JSON.stringify(pushPayload)
1143                        )
1144
1145                    };
1146                    // $("#notify").text("initiate call");
1147                    QB.pushnotifications.events.create(params, function (err, response) {
1148                        if (err) {
1149                            console.debug('[pushnotifications-error]', err);
1150                        } else {
1151                            // success
1152                            $("#notify").text("Push Notification is sent");
1153                            console.log("Push Notification is sent.");
1154                        }
1155                    });
1156                }
1157            });
1158        }
1159    });
1160
1161    // check the current session state
1162    /** DECLINE */
1163    $(document).on('click', '.j-decline', function () {
1164        var baseUrl = '<?php echo \Yii::$app->request->baseUrl; ?>';
1165        var url = baseUrl + '/call/status-call';
1166        // TODO uncomme
1167        // $.ajax({
1168        //     url: url,
1169        //     type: 'POST',
1170        //     dataType: 'json',
1171        //     data: {
1172        //         'rtc_id': app.currentSession.ID,
1173        //         'status': 'reject',
1174        //         'receiver_id': app.caller['id'],
1175        //     },
1176        //     contentType: 'application/x-www-form-urlencoded;charset=ISO-8859-15',
1177        //     async: false,
1178        //     success: function (response) {
1179        //         console.log('success');
1180        //     },
1181        //     error: function (request, error) {
1182        //         console.log(error);
1183        //     }
1184        // });
1185        if (!_.isEmpty(app.currentSession)) {
1186            app.currentSession.reject({});
1187            $(ui.income_call).modal('hide');
1188            document.getElementById(sounds.rington).pause();
1189            $('.close').trigger('click');
1190            app.helpers.stateBoard.update({
1191                'title': 'tpl_default',
1192                'property': {
1193                    'name': app.caller.full_name,
1194                }
1195            });
1196            $("#notify").text("call Rejected!");
1197            rejectcall = "";
1198        }
1199    });
1200    /** ACCEPT */
1201    $(document).on('click', '.j-accept', function () {
1202        $(this).addClass('hide');
1203        var baseUrl = '<?php echo \Yii::$app->request->baseUrl; ?>';
1204        var url = baseUrl + '/call/status-call';
1205        // var url = window.location.origin+'/call/status-call';
1206        //TODO uncomment this line
1207        // $.ajax({
1208        //     url: url,
1209        //     type: 'POST',
1210        //     dataType: 'json',
1211        //     data: {
1212        //         'rtc_id': app.currentSession.ID,
1213        //         'status': 'accept',
1214        //         'receiver_id': app.caller['id'],
1215        //         'call_time': app.caller['last_request_at'],
1216        //     },
1217        //     contentType: 'application/x-www-form-urlencoded;charset=ISO-8859-15',
1218        //     async: false,
1219        //     success: function (response) {
1220        //         console.log('success');
1221        //     },
1222        //     error: function (request, error) {
1223        //         console.log(error);
1224        //     }
1225
1226        // });
1227        isAudio = app.currentSession.callType === QB.webrtc.CallType.AUDIO;
1228        var $videoSourceFilter = $(ui.videoSourceFilter),
1229            $audioSourceFilter = $(ui.audioSourceFilter),
1230            mediaParams;
1231        console.dir(isAudio);
1232        if (isAudio) {
1233            mediaParams = {
1234                audio: true,
1235                video: false
1236            };
1237            document.querySelector('.j-actions[data-call="video"]').setAttribute('hidden', true);
1238            $('.j-fullscreen').addClass('hide');
1239            $('.j-caller__ctrl[data-target="screen"]').addClass('hide');
1240        } else {
1241            mediaParams = {
1242                audio: {
1243                    deviceId: $audioSourceFilter.val() ? $audioSourceFilter.val() : undefined
1244                },
1245                video: {
1246                    deviceId: $videoSourceFilter.val() ? { exact: $videoSourceFilter.val() } : undefined
1247                },
1248                elemId: 'localVideo',
1249                options: {
1250                    muted: true,
1251                    mirror: true
1252                }
1253            };
1254            document.querySelector('.j-actions[data-call="audio"]').setAttribute('hidden', true);
1255            $('.j-fullscreen').removeClass('hide');
1256            $('.j-caller__ctrl[data-target="screen"]').removeClass('hide');
1257        }
1258        var videoElems = '';
1259        // TODO: Remove
1260        $(ui.income_call).modal('hide');
1261        document.getElementById(sounds.rington).pause();
1262        app.currentSession.getUserMedia(mediaParams, function (err, stream) {
1263            if (err || !stream.getAudioTracks().length || (isAudio ? false : !stream.getVideoTracks().length)) {
1264                var errorMsg = '';
1265                app.currentSession.stop({
1266
1267                });
1268                app.helpers.stateBoard.update({
1269                    'title': 'tpl_device_not_found',
1270                    'isError': 'qb-error',
1271                    'property': {
1272                        'name': app.caller.full_name
1273                    }
1274                });
1275            } else {
1276                var opponents = [app.currentSession.initiatorID],
1277                    compiled = _.template($('#callee_video').html());
1278                $('.j-actions').addClass('hangup');
1279                /* alert("hangup-3")*/
1280                $(ui.bandwidthSelect).attr('disabled', true);
1281                /** get all opponents */
1282                app.currentSession.opponentsIDs.forEach(function (userID, i, arr) {
1283                    if (userID != app.currentSession.currentUserID) {
1284                        opponents.push(userID);
1285                    }
1286                });
1287                opponents.forEach(function (userID, i, arr) {
1288                    var peerState = app.currentSession.connectionStateForUser(userID),
1289                        userInfo = _.findWhere(app.users, { 'id': +userID });
1290                    if ((document.getElementById('remote_video_' + userID) === null)) {
1291                        videoElems += compiled({
1292                            'userID': userID,
1293                            'name': userInfo ? userInfo.full_name : 'userID ' + userID,
1294                            'state': app.helpers.getConStateName(peerState)
1295                        });
1296                        if (peerState === QB.webrtc.PeerConnectionState.CLOSED) {
1297                            app.helpers.toggleRemoteVideoView(userID, 'clear');
1298                        }
1299                    }
1300                });
1301
1302
1303                if (app.currentSession.opponentsIDs.length >= 2) {
1304                    $('.j-callees').append(videoElems);
1305
1306                }
1307                app.helpers.stateBoard.update({
1308                    'title': 'tpl_during_call',
1309                    'property': {
1310                        'name': app.caller.full_name
1311                    }
1312                });
1313
1314                /* app.helpers.setFooterPosition();*/
1315                app.currentSession.accept({});
1316            }
1317        });
1318        $("#notify").text("accept function");
1319    });
1320
1321    /** CHANGE FILTER */
1322    $(document).on('change', ui.filterSelect, function () {
1323        var filterName = $.trim($(this).val());
1324        app.helpers.changeFilter('#localVideo', filterName);
1325        if (!_.isEmpty(app.currentSession)) {
1326            app.currentSession.update({ 'filter': filterName });
1327        }
1328    });
1329
1330    /** CHANGE SOURCE */
1331    $(document).on('click', '.j-confirm_media', function () {
1332        switchMediaTracks();
1333    });
1334
1335    $(document).on('click', '.j-callees__callee__video', function () {
1336        var $that = $(this),
1337            userId = +($(this).data('user')),
1338            activeClass = [];
1339        if (app.currentSession.peerConnections[userId].stream && !$that.srcObject) {
1340            if ($that.hasClass('active')) {
1341                return false;
1342            } else {
1343                if (recorder) {
1344                    recorder.stop();
1345                }
1346                $('.j-callees__callee__video').removeClass('active');
1347                $that.addClass('active');
1348                app.helpers.changeFilter('#main_video', 'no');
1349                activeClass = _.intersection($that.attr('class').split(/\s+/), app.filter.names.split(/\s+/));
1350                /** set filter to main video if exist */
1351                if (activeClass.length) {
1352                    app.helpers.changeFilter('#main_video', activeClass[0]);
1353                }
1354                app.currentSession.attachMediaStream('main_video', app.currentSession.peerConnections[userId].stream);
1355                $('#main_video').css('border-radius', '0');
1356                $('#main_video').css('background-image', '');
1357                $('#main_video').css('height', '100%');
1358                $('#main_video').css('width', '100%');
1359                app.mainVideo = userId;
1360            }
1361        }
1362    });
1363
1364    $(document).on('click', '.j-caller__ctrl[data-target="screen"]', function () {
1365        if (_.isEmpty(app.currentSession)) {
1366            return false;
1367        }
1368        var $btn = $(this),
1369            isActive = $btn.hasClass('active'),
1370            runScreenSharing = function () {
1371                navigator.mediaDevices.getDisplayMedia({
1372                    video: true,
1373                }).then(stream => {
1374                    var videoTrack = stream.getVideoTracks()[0];
1375                    videoTrack.onended = stopScreenSharing;
1376                    switchMediaTrack(videoTrack);
1377                    $btn.addClass('active');
1378                });
1379            },
1380            stopScreenSharing = function () {
1381                navigator.mediaDevices.getUserMedia({
1382                    video: true,
1383                }).then(stream => {
1384                    switchMediaTrack(stream.getVideoTracks()[0]);
1385                    $btn.removeClass('active');
1386                });
1387            },
1388            switchMediaTrack = function (track) {
1389                app.currentSession.localStream.getVideoTracks()[0].stop();
1390                var stream = app.currentSession.localStream.clone();
1391                stream.removeTrack(stream.getVideoTracks()[0]);
1392                stream.addTrack(track);
1393                app.currentSession.localStream.getAudioTracks()[0].stop();
1394                app.currentSession._replaceTracks(stream);
1395                app.currentSession.localStream = stream;
1396                return true;
1397            };
1398
1399        if (isActive) {
1400            stopScreenSharing();
1401        } else {
1402            runScreenSharing();
1403        }
1404    });
1405
1406    $(document).on('click', '.j-caller__ctrl', function () {
1407        var $btn = $(this),
1408            isActive = $btn.hasClass('active');
1409        if (_.isEmpty(app.currentSession) || $btn.data('target') == 'screen') {
1410            return false;
1411        }
1412        if (isActive) {
1413            $btn.removeClass('active');
1414            app.currentSession.unmute($btn.data('target'));
1415        } else {
1416            $btn.addClass('active');
1417            app.currentSession.mute($btn.data('target'));
1418        }
1419    });
1420
1421    $(document).on('click', '.j-fullscreen', function () {
1422        console.log("hitting")
1423        var elem = document.getElementById("main_video");
1424        console.log(elem)
1425        if (elem.requestFullscreen) {
1426            elem.requestFullscreen();
1427        } else if (elem.mozRequestFullScreen) { /* Firefox */
1428            elem.mozRequestFullScreen();
1429        } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
1430            elem.webkitRequestFullscreen();
1431        } else if (elem.msRequestFullscreen) { /* IE/Edge */
1432            elem.msRequestFullscreen();
1433        }
1434    });
1435
1436    /** Video recording */
1437    $(document).on('click', '.j-record', function () {
1438        var $btn = $(this),
1439            isActive = $btn.hasClass('active');
1440        if (_.isEmpty(app.currentSession)) {
1441            return false;
1442        } else if (QBMediaRecorder.isAvailable()) {
1443            if (!isActive) {
1444                var connections = app.currentSession.peerConnections,
1445                    connection = connections[app.mainVideo];
1446                if (!connection) {
1447                    // alert("pel hehrwrwrwrwrwerwerw");
1448                    return false;
1449                }
1450                recorder = new QBMediaRecorder(recorderOpts);
1451                var elem = document.getElementById("main_video");
1452                if (typeof elem.srcObject === 'object') {
1453                    recorder.start(elem.srcObject);
1454                }
1455            } else {
1456                recorder.stop();
1457            }
1458        }
1459    });
1460
1461    /** LOGOUT */
1462    $(document).on('click', '.j-logout', function () {
1463        app.caller = {};
1464        app.users = [];
1465        QB.chat.disconnect();
1466        QB.destroySession(() => null);
1467        app.currentSession = {};
1468        QB.webrtc.sessions = {};
1469        localStorage.removeItem('isAuth');
1470        localStorage.removeItem('data');
1471        localStorage.removeItem('name1');
1472        localStorage.removeItem('name2');
1473        localStorage.removeItem('name3');
1474        app.router.navigate('join', { 'trigger': true });
1475        /*app.helpers.setFooterPosition();*/
1476
1477    });
1478
1479    /** Close tab or browser */
1480    /* $( window ).unload(function() {
1481         localStorage.removeItem('isAuth');
1482     });*/
1483
1484    /**
1485     * QB Event listener.
1486     *
1487     * [Recommendation]
1488     * We recomend use Function Declaration
1489     * that SDK could identify what function(listener) has error
1490     *
1491     * Chat:
1492     * - onDisconnectedListener
1493     * WebRTC:
1494     * - onCallListener
1495     * - onCallStatsReport
1496     * - onUpdateCallListener
1497     *
1498     * - onAcceptCallListener
1499     * - onRejectCallListener
1500     * - onUserNotAnswerListener
1501     *
1502     * - onRemoteStreamListener
1503     *
1504     * - onStopCallListener
1505     * - onSessionCloseListener
1506     * - onSessionConnectionStateChangedListener
1507     * 
1508     * - onDevicesChangeListener
1509     */
1510
1511    QB.chat.onDisconnectedListener = function () {
1512        //alert("lst-1");
1513        console.log('onDisconnectedListener.');
1514    };
1515
1516    QB.chat.onContactListListener = function (userId, type) {
1517        console.log('ContactListListener');
1518        // console.debug(userId, "ddddd");
1519        // app.c
1520
1521        /// TODo ADDD
1522        //console.log(type);
1523        //let user_li =$("#userListContainer").find('li [data-cid="'+userId+'"]');
1524
1525        if ($("#userListContainer").find('li[data-cid="' + userId + '"]').length) {
1526            if (type == 'unavailable') {
1527                console.log($("#userListContainer").find('li [data-cid="' + userId + '"]'));
1528                $("#userListContainer").find('li[data-cid="' + userId + '"]').find("div.status-circle").removeClass("online-user");
1529            } else {
1530                //console.log(document.querySelector("li[data-cid='"+userId+"']").querySelector('div.status-circle'));
1531                $("#userListContainer").find('li[data-cid="' + userId + '"]').find("div.status-circle").addClass("online-user");
1532                console.log($('*[data-cid="' + userId + '"]'));
1533            }
1534        }
1535
1536        // if(typeof type == "undefined"){
1537        //     console.log('undd');
1538        // }
1539        // type - if a user left the chat, type will be 'unavailable'.
1540        // Otherwise - 'available'.
1541    };
1542
1543    QB.webrtc.onCallStatsReport = function onCallStatsReport(session, userId, stats, error) {
1544        //alert("lst-2");            
1545        $("#notify").text("CallStatsReport");
1546        // console.group('onCallStatsReport');
1547        // console.log('userId: ', userId);
1548        // console.log('session: ', session);
1549        // console.log('stats: ', stats);
1550        console.groupEnd();
1551        if (stats.remote.video.bitrate) {
1552            $('#bitrate_' + userId).text('video bitrate: ' + stats.remote.video.bitrate);
1553        } else if (stats.remote.audio.bitrate) {
1554            $('#bitrate_' + userId).text('audio bitrate: ' + stats.remote.audio.bitrate);
1555        }
1556    };
1557
1558    QB.webrtc.onSessionCloseListener = function onSessionCloseListener(session) {
1559        // alert("lst-3");          
1560        $("#notify").text("SessionCloseListener");
1561        //  alert('Please check your audio video devices');
1562        $("#income_caller_name").addClass('hide');
1563        $(".income_call").modal('hide');
1564        $("#myModalAV .j-accept").first().addClass('hide');
1565        // TODO: Remove
1566        // $("#myModalAV").modal('hide');
1567        $('.close').trigger('click');
1568        // console.log('onSessionCloseListener: ', session);
1569        $('#reviewModel').modal('show');
1570        document.getElementById(sounds.call).pause();
1571        document.getElementById(sounds.end).play();
1572        if (call.callTimer) {
1573            $('#timer').addClass('invisible');
1574            clearInterval(call.callTimer);
1575            call.callTimer = null;
1576            call.callTime = 0;
1577            app.helpers.network = {};
1578        }
1579        $('.j-actions').removeClass('hangup');
1580        $('.j-actions_group').removeClass('hangup');
1581        $('.j-caller__ctrl').removeClass('active');
1582        $(ui.bandwidthSelect).attr('disabled', false);
1583        $('.j-callees').empty();
1584        $('.frames_callee__bitrate').hide();
1585        app.currentSession.detachMediaStream('main_video');
1586        app.currentSession.detachMediaStream('localVideo');
1587        remoteStreamCounter = 0;
1588        if (session.opponentsIDs.length > 1) {
1589            app.helpers.stateBoard.update({
1590                'title': 'tpl_call_stop',
1591                'property': {
1592                    'name': app.caller.full_name
1593                }
1594            });
1595        } else {
1596            app.helpers.stateBoard.update({
1597                title: 'tpl_default',
1598                property: {
1599                    'name': app.caller.full_name,
1600                }
1601            });
1602        }
1603
1604        if (document.querySelector('.j-actions[hidden]')) {
1605            document.querySelector('.j-actions[hidden]').removeAttribute('hidden');
1606        }
1607        if (document.querySelector('.j-caller__ctrl')) {
1608            document.querySelector('.j-caller__ctrl').removeAttribute('hidden');
1609        }
1610
1611    };
1612
1613    QB.webrtc.onUserNotAnswerListener = function onUserNotAnswerListener(session, userId) {
1614        //alert("lst-4");            
1615        $("#notify").text("UserNotAnswerListener");
1616        // console.group('onUserNotAnswerListener.');
1617        // console.log('UserId: ', userId);
1618        // console.log('Session: ', session);
1619        console.groupEnd();
1620        var opponent = _.findWhere(app.users, { 'id': +userId });
1621
1622        /** It's for p2p call */
1623        if (session.opponentsIDs.length === 1) {
1624            app.helpers.stateBoard.update({
1625                'title': 'p2p_call_stop',
1626                'property': {
1627                    'name': opponent.full_name,
1628                    // 'currentName': app.caller.full_name,
1629                    'reason': 'not answered'
1630                }
1631            });
1632            var call_type = isAudio === true ? 'audio' : 'video';
1633            var baseUrl = '<?php echo \Yii::$app->request->baseUrl; ?>';
1634            var url = baseUrl + '/call/status-call';
1635            // var url = window.location.origin+'/call/status-call';
1636            /// TODO Uncomment this 
1637            // $.ajax({
1638            //     url: url,
1639            //     type: 'POST',
1640            //     dataType: 'json',
1641            //     data: {
1642            //         'rtc_id': app.currentSession.ID,
1643            //         'status': '',
1644            //         'receiver_id': app.caller['id'],
1645            //         'call_time': app.caller['last_request_at'],
1646            //     },
1647            //     contentType: 'application/x-www-form-urlencoded;charset=ISO-8859-15',
1648            //     async: false,
1649            //     success: function (response) {
1650            //         console.log('success');
1651            //     },
1652            //     error: function (request, error) {
1653            //         console.log(error);
1654            //     }
1655
1656            // });
1657        } else {
1658            $('.j-callee_status_' + userId).text('No Answer');
1659            var baseUrl = '<?php echo \Yii::$app->request->baseUrl; ?>';
1660            var url = baseUrl + '/call/status-call';
1661            // var url = window.location.origin+'/call/status-call';
1662            // TODO uncomment this
1663            // $.ajax({
1664            //     url: url,
1665            //     type: 'POST',
1666            //     dataType: 'json',
1667            //     data: {
1668            //         'rtc_id': app.currentSession.ID,
1669            //         'status': '',
1670            //         'receiver_id': app.caller['id'],
1671            //         'call_time': app.caller['last_request_at'],
1672            //     },
1673            //     contentType: 'application/x-www-form-urlencoded;charset=ISO-8859-15',
1674            //     async: false,
1675            //     success: function (response) {
1676            //         console.log('success');
1677            //     },
1678            //     error: function (request, error) {
1679            //         console.log(error);
1680            //     }
1681
1682            // });
1683        }
1684    };
1685
1686    QB.webrtc.onCallListener = function onCallListener(session, extension) {
1687        //alert("lst-5="+session.opponentsIDs.length);
1688        if (session.opponentsIDs.length > 1) {
1689            $(".person_type_g").removeClass("hide");
1690        }
1691        $("#notify").text("A new call session has been received.");
1692        // $('#model_call').trigger('click');
1693        $("#income_caller_name").removeClass('hide');
1694        $('.j-fullscreen').addClass("hide");
1695        $('.j-caller__ctrl[data-target="screen"]').addClass("hide");
1696        $("#myModalAV .j-accept").first().removeClass('hide');
1697        $("#myModalAV").modal('show');
1698        // if(isAudio) {
1699        var dataCid = session.initiatorID;
1700        var img_type = $('*[data-cid="' + dataCid + '"]').data("profile");
1701        //   alert(img_type);
1702        //var img_type = $("#userListContainer li").attr("data-cid",dataCid).data("profile");
1703        // var img_type = $("#profileUserImage").val();
1704        $('#main_video').css('background-image', 'url(' + img_type + ')');
1705        $('#main_video').css('background-size', 'cover');
1706        //$('#main_video').css('background-position', 'center top');      
1707        $('#main_video').css('width', '200px');
1708        $('#main_video').css('height', '200px');
1709        $('#main_video').css('border-radius', '50%');
1710        $('#main_video').css('background-position', 'center');
1711        var local = $("#local-img").attr("src");
1712        $('#localVideo').css('background-image', 'url(' + local + ')');
1713        $('#localVideo').css('background-size', 'cover');
1714        $('#localVideo').css('background-position', 'center top');
1715
1716
1717        if (session.opponentsIDs.length == 1) {
1718            $(".caller__frames").css({
1719                width: "15%",
1720                height: "auto",
1721                "border-top": "none",
1722                "border-right": "none",
1723                "border-bottom": "0px",
1724                "border-left": "none",
1725                "border-image": "initial",
1726                position: "absolute",
1727                bottom: "0px",
1728                right: "0px",
1729                padding: "0px",
1730                "border-radius": "6px 6px 0px 0px",
1731                overflow: "hidden",
1732                background: "#777777",
1733
1734            })
1735        }
1736
1737
1738        // .qb-video
1739        // position: relative;
1740        // padding: 0 0 75% 0;
1741        // /* background: #bfbfbf; */
1742        // background: #000;
1743        // }
1744        /*alert("=="+local);*/
1745        console.group('onCallListener.');
1746        // console.log('Session: ', session);
1747        // console.log('Extension: ', extension);
1748        console.groupEnd();
1749
1750        app.currentSession = session;
1751        // console.log("[onCallListener]",app.currentSession);
1752        QB.users.get(Number(session.initiatorID), function (error, user) {
1753            if (error) {
1754                console.log(error);
1755            } else {
1756                /*alert("call Listener-4");*/
1757                app.users = app.users.filter(function (item) {
1758                    return user.id !== item.id;
1759                });
1760                app.users.push(user);
1761                /** close previous modal */
1762                $(ui.income_call).modal('hide');
1763                $('.j-ic_initiator').text(user.full_name);
1764                // check the current session state
1765                if (app.currentSession.state !== QB.webrtc.SessionConnectionState.CLOSED) {
1766                    //$(ui.income_call).modal('show');
1767                    document.getElementById(sounds.rington).play();
1768                }
1769            }
1770        });
1771    };
1772
1773    QB.webrtc.onRejectCallListener = function onRejectCallListener(session, userId, extension) {
1774        app.callees[userId] = userId;
1775
1776        //alert("lst-6="+rejectcall);
1777        $("#notify").text("RejectCallListener");
1778        $(".j-callee_status_" + userId).text("Rejected");
1779        //  $('.close').trigger('click');
1780        // console.log("[app.currentSession.ID]",app.currentSession.ID);
1781        // console.log("[=.session=]",userId);
1782        if (app.currentSession.ID === session.ID) {
1783            //  alert("same");
1784            document.getElementById(sounds.rington).pause();
1785            return true;
1786        }
1787        if (app.currentSession.ID !== session) {
1788            return;
1789        }
1790
1791        if (call.callTimer) {
1792            $('#timer').addClass('invisible');
1793            clearInterval(call.callTimer);
1794            call.callTimer = null;
1795            call.callTime = 0;
1796            app.helpers.network = {};
1797        }
1798
1799        console.group('onRejectCallListener.');
1800        // console.log('UserId: ' + userId);
1801        // console.log('Session: ' + session);
1802        // console.log('Extension: ' + JSON.stringify(extension));
1803        console.groupEnd();
1804
1805        var user = _.findWhere(app.users, { 'id': +userId }),
1806            userCurrent = _.findWhere(app.users, { 'id': +session.currentUserID });
1807        app.helpers.notifyIfUserLeaveCall(session, userId, 'hung up the call', 'Hung Up');
1808        /** It's for p2p call */
1809        if (session.opponentsIDs.length === 1) {
1810            app.helpers.stateBoard.update({
1811                'title': 'p2p_call_stop',
1812                'property': {
1813                    'name': user.full_name,
1814                    'currentName': userCurrent.full_name,
1815                    'reason': 'rejected the call'
1816                }
1817            });
1818        } else {
1819            var userInfo = _.findWhere(app.users, { 'id': +userId });
1820            app.calleesRejected.push(userInfo);
1821            $('.j-callee_status_' + userId).text('Rejected');
1822        }
1823    };
1824
1825    QB.webrtc.onStopCallListener = function onStopCallListener(session, userId, extension) {
1826        // alert("lst-7");
1827        document.getElementById(sounds.rington).pause();
1828        $("#notify").text("onStopCallListener");
1829        console.group('onStopCallListener.');
1830        // console.log('UserId: ', userId);
1831        // console.log('Session: ', session);
1832        // console.log('Extension: ', extension);
1833        console.groupEnd();
1834        app.helpers.notifyIfUserLeaveCall(session, userId, 'hung up the call', 'Hung Up');
1835        if (recorder) {
1836            recorder.stop();
1837        }
1838        opponents_close(session, userId, extension);
1839    };
1840
1841    QB.webrtc.onAcceptCallListener = function onAcceptCallListener(session, userId, extension) {
1842        //alert("lst-8");            
1843        $("#notify").text("onAcceptCallListener");
1844        console.group('onAcceptCallListener.');
1845        // console.log('UserId: ', userId);
1846        // console.log('Session-onAcceptCallListener: ', session);
1847        // console.log('Extension: ', extension);
1848        console.groupEnd();
1849        var userInfo = _.findWhere(app.users, { 'id': +userId }),
1850            filterName = $.trim($(ui.filterSelect).val());
1851        document.getElementById(sounds.call).pause();
1852        app.currentSession.update({ 'filter': filterName });
1853        /** update list of callee who take call */
1854        app.calleesAnwered.push(userInfo);
1855        if (app.currentSession.currentUserID === app.currentSession.initiatorID) {
1856            app.helpers.stateBoard.update({
1857                'title': 'tpl_call_status',
1858                'property': {
1859                    'users': app.helpers.getUsersStatus()
1860                }
1861            });
1862        }
1863    };
1864
1865    QB.webrtc.onRemoteStreamListener = (session, userId, stream) => {
1866        //alert("lst-9");            
1867        $("#notify").text("onRemoteStreamListener");
1868        console.group('onRemoteStreamListener.');
1869        // console.log('userId: ', userId);
1870        console.log('Session: ', session);
1871        // console.log('Stream: ', stream);
1872        console.groupEnd();
1873        var state = app.currentSession.connectionStateForUser(userId),
1874            peerConnList = QB.webrtc.PeerConnectionState;
1875        if (state === peerConnList.DISCONNECTED || state === peerConnList.FAILED || state === peerConnList.CLOSED) {
1876            return false;
1877        }
1878        if (app.currentSession.opponentsIDs.length >= 2) {
1879            // console.info('onRemoteStreamListener add video to the video element', stream);
1880            app.currentSession.attachMediaStream('remote_video_' + userId, stream);
1881            if (remoteStreamCounter === 0) {
1882                $('#remote_video_' + userId).click();
1883                app.mainVideo = userId;
1884                ++remoteStreamCounter;
1885            }
1886        } else {
1887            app.currentSession.attachMediaStream('main_video', stream);
1888
1889        }
1890        if (!call.callTimer) {
1891            call.callTimer = setInterval(function () { call.updTimer.call(call); }, 1000);
1892        }
1893        $('.frames_callee__bitrate').show();
1894        $('.j-fullscreen').removeClass('hide');
1895        $('.j-caller__ctrl[data-target="screen"]').removeClass('hide');
1896    };
1897
1898    QB.webrtc.onUpdateCallListener = (session, userId, extension) => {
1899        //alert("lst-10");           
1900        $("#notify").text("UpdateCallListener-Called when updates to the active call ");
1901        console.group('onUpdateCallListener.');
1902        // console.log('UserId: ' + userId);
1903        // console.log('Session: ' + session);
1904        // console.log('Extension: ' + JSON.stringify(extension));
1905        console.groupEnd();
1906
1907        if ($('#remote_video_' + userId)) {
1908
1909            app.helpers.changeFilter('#remote_video_' + userId, extension.filter);
1910        }
1911
1912
1913
1914        if (+(app.mainVideo) === userId) {
1915            app.helpers.changeFilter('#main_video', extension.filter);
1916        }
1917    };
1918
1919    QB.webrtc.onSessionConnectionStateChangedListener = (session, userId, connectionState) => {
1920        console.debug("onSessionConnectionStateChanged")
1921        console.debug("connectionState")
1922        $("#notify").text("SessionConnectionStateChangedListener-A peer connection state has been changed.");
1923        initiatorID = session.initiatorID;
1924
1925
1926        var connectionStateName = _.invert(QB.webrtc.SessionConnectionState)[connectionState],
1927            $calleeStatus = $('.j-callee_status_' + userId),
1928            isCallEnded = false;
1929        if (connectionState === QB.webrtc.SessionConnectionState.CONNECTING) {
1930            $calleeStatus.text(connectionStateName);
1931        }
1932        if (connectionState === QB.webrtc.SessionConnectionState.CONNECTED) {
1933            app.helpers.toggleRemoteVideoView(userId, 'show');
1934            $calleeStatus.text(connectionStateName);
1935        }
1936        if (connectionState === QB.webrtc.SessionConnectionState.COMPLETED) {
1937            app.helpers.toggleRemoteVideoView(userId, 'show');
1938            $calleeStatus.text('connected');
1939        }
1940        if (connectionState === QB.webrtc.SessionConnectionState.DISCONNECTED) {
1941            app.helpers.toggleRemoteVideoView(userId, 'hide');
1942            $calleeStatus.text('disconnected');
1943        }
1944
1945        if (connectionState === QB.webrtc.SessionConnectionState.CLOSED) {
1946            app.helpers.toggleRemoteVideoView(userId, 'clear');
1947            if (app.mainVideo === userId) {
1948                $('#remote_video_' + userId).removeClass('active');
1949                app.helpers.changeFilter('#main_video', 'no');
1950                app.mainVideo = 0;
1951                for (var key in app.currentSession.peerConnections) {
1952                    if (key != userId
1953                        && app.currentSession.peerConnections[key].stream !== undefined
1954                        && app.currentSession.peerConnections[key].stream.active) {
1955                        app.currentSession.attachMediaStream('main_video', app.currentSession.peerConnections[key].stream);
1956                        app.mainVideo = key;
1957                        break;
1958                    }
1959                }
1960            }
1961            if (!_.isEmpty(app.currentSession)) {
1962                if (Object.keys(app.currentSession.peerConnections).length === 1 || userId === app.currentSession.initiatorID) {
1963                    $(ui.income_call).modal('hide');
1964                    document.getElementById(sounds.rington).pause();
1965                }
1966            }
1967            isCallEnded = _.every(app.currentSession.peerConnections, function (i) {
1968                return i.iceConnectionState === 'closed';
1969            });
1970
1971            /** remove filters */
1972
1973            if (isCallEnded) {
1974                app.helpers.changeFilter('#localVideo', 'no');
1975                app.helpers.changeFilter('#main_video', 'no');
1976                $(ui.filterSelect).val('no');
1977
1978                app.calleesAnwered = [];
1979                app.calleesRejected = [];
1980                app.network[userId] = null;
1981            }
1982
1983            if (app.currentSession.currentUserID === app.currentSession.initiatorID && !isCallEnded) {
1984                var userInfo = _.findWhere(app.users, { 'id': +userId });
1985
1986                /** get array if users without user who ends call */
1987                app.calleesAnwered = _.reject(app.calleesAnwered, function (num) { return num.id === +userId; });
1988                app.calleesRejected.push(userInfo);
1989
1990                app.helpers.stateBoard.update({
1991                    'title': 'tpl_call_status',
1992                    'property': {
1993                        'users': app.helpers.getUsersStatus()
1994                    }
1995                });
1996            }
1997
1998            if (_.isEmpty(app.currentSession) || isCallEnded) {
1999                if (call.callTimer) {
2000                    $('#timer').addClass('invisible');
2001                    clearInterval(call.callTimer);
2002                    call.callTimer = null;
2003                    call.callTime = 0;
2004                    app.helpers.network = {};
2005                }
2006            }
2007        }
2008
2009        if (session.opponentsIDs.length == 1) {
2010            $("#main_video").css({
2011                " background-repeat": " no-repeat",
2012                "background-image": "none",
2013                "background-size": "auto",
2014                "width": "100%",
2015                "height": "100%",
2016                "border-radius": 0,
2017                "background-position": "center center",
2018                "display": "block",
2019            })
2020            $(".caller__frames").css({
2021                width: "15%",
2022                height: "auto",
2023                "border-top": "none",
2024                "border-right": "none",
2025                "border-bottom": "0px",
2026                "border-left": "none",
2027                "border-image": "initial",
2028                position: "absolute",
2029                bottom: "0px",
2030                right: "0px",
2031                padding: "0px",
2032                "border-radius": "6px 6px 0px 0px",
2033                overflow: "hidden",
2034                background: "#777777",
2035
2036            })
2037        }
2038
2039        if (session.opponentsIDs.length >= 2 && session.opponentsIDs.length < 4) {
2040            $("#main_video").css("display", "none");
2041            $(".caller__frames").css({ "width": "51%", "height": "50%", "border": "none", "position": "absolute", "bottom": "0", "right": "0", "padding": "2%", "border-bottom": "0", "border-radius": "6px 6px 0 0", "overflow": "hidden", "background": "#777777" });
2042        } else if (ession.opponentsIDs.length > 4 && session.opponentsIDs.length < 5) {
2043            $("#main_video").css("display", "none");
2044
2045            $(".caller__frames").css({ "width": "15%", "border": "1px solid #555555", "position": "absolute", "bottom": "0", "right": "0", "padding": "0", "border-bottom": "0", "border-radius": "6px 6px 0 0", "overflow": "hidden", "background": "#777777" });
2046        } else if (session.opponentsIDs.length > 2 && session.opponentsIDs.length < 4) {
2047            $("#main_video").css("display", "none");
2048
2049            $(".caller__frames").css({ "width": "51%", "height": "50%", "border": "none", "position": "absolute", "bottom": "0", "right": "0", "padding": "2%", "border-bottom": "0", "border-radius": "6px 6px 0 0", "overflow": "hidden", "background": "#777777" });
2050        }
2051
2052    }
2053    // QB.webrtc.onSessionConnectionStateChangedListener = function onSessionConnectionStateChangedListener(session, userId, connectionState) {
2054    //     //alert("lst-11="+session.opponentsIDs.length);  
2055    //     $("#notify").text("SessionConnectionStateChangedListener-A peer connection state has been changed.");
2056    //     console.group('onSessionConnectionStateChangedListener.dddddd');
2057    //     // console.log('UserID:', userId);
2058    //     // console.log('Session:', session);
2059    //     // console.log('Сonnection state:', connectionState, statesPeerConn[connectionState]);
2060    //     // console.log('[connectionState]:', connectionState);
2061    //     // console.log('[statesPeerConn[connectionState]]:',statesPeerConn[connectionState]);
2062    //     initiatorID = session.initiatorID;
2063    //     //  alert("test2="+Session.opponentsIDs);
2064    //     // console.log("[=.session=]",session.initiatorID);
2065    //     // console.log("[=.opponentsIDs=]",session.opponentsIDs);
2066    //     console.groupEnd();
2067
2068    //     // TODO
2069    //     var connectionStateName = _.invert(QB.webrtc.SessionConnectionState)[connectionState],
2070    //         $calleeStatus = $('.j-callee_status_' + userId),
2071    //         isCallEnded = false;
2072    //     if (connectionState === QB.webrtc.SessionConnectionState.CONNECTING) {
2073    //         $calleeStatus.text(connectionStateName);
2074    //     }
2075    //     if (connectionState === QB.webrtc.SessionConnectionState.CONNECTED) {
2076    //         app.helpers.toggleRemoteVideoView(userId, 'show');
2077    //         $calleeStatus.text(connectionStateName);
2078    //     }
2079    //     if (connectionState === QB.webrtc.SessionConnectionState.COMPLETED) {
2080    //         app.helpers.toggleRemoteVideoView(userId, 'show');
2081    //         $calleeStatus.text('connected');
2082    //     }
2083    //     if (connectionState === QB.webrtc.SessionConnectionState.DISCONNECTED) {
2084    //         app.helpers.toggleRemoteVideoView(userId, 'hide');
2085    //         $calleeStatus.text('disconnected');
2086    //     }
2087
2088    //     if (connectionState === QB.webrtc.SessionConnectionState.CLOSED) {
2089    //         app.helpers.toggleRemoteVideoView(userId, 'clear');
2090    //         if (app.mainVideo === userId) {
2091    //             $('#remote_video_' + userId).removeClass('active');
2092    //             app.helpers.changeFilter('#main_video', 'no');
2093    //             app.mainVideo = 0;
2094    //             for (var key in app.currentSession.peerConnections) {
2095    //                 if (key != userId
2096    //                     && app.currentSession.peerConnections[key].stream !== undefined
2097    //                     && app.currentSession.peerConnections[key].stream.active) {
2098    //                     app.currentSession.attachMediaStream('main_video', app.currentSession.peerConnections[key].stream);
2099    //                     app.mainVideo = key;
2100    //                     break;
2101    //                 }
2102    //             }
2103    //         }
2104    //         if (!_.isEmpty(app.currentSession)) {
2105    //             if (Object.keys(app.currentSession.peerConnections).length === 1 || userId === app.currentSession.initiatorID) {
2106    //                 alert("dddd")
2107    //                 $(ui.income_call).modal('hide');
2108    //                 document.getElementById(sounds.rington).pause();
2109    //             }
2110    //         }
2111    //         isCallEnded = _.every(app.currentSession.peerConnections, function (i) {
2112    //             return i.iceConnectionState === 'closed';
2113    //         });
2114
2115    //         /** remove filters */
2116
2117    //         if (isCallEnded) {
2118    //             app.helpers.changeFilter('#localVideo', 'no');
2119    //             app.helpers.changeFilter('#main_video', 'no');
2120    //             $(ui.filterSelect).val('no');
2121
2122    //             app.calleesAnwered = [];
2123    //             app.calleesRejected = [];
2124    //             app.network[userId] = null;
2125    //         }
2126
2127    //         if (app.currentSession.currentUserID === app.currentSession.initiatorID && !isCallEnded) {
2128    //             var userInfo = _.findWhere(app.users, { 'id': +userId });
2129
2130    //             /** get array if users without user who ends call */
2131    //             app.calleesAnwered = _.reject(app.calleesAnwered, function (num) { return num.id === +userId; });
2132    //             app.calleesRejected.push(userInfo);
2133
2134    //             app.helpers.stateBoard.update({
2135    //                 'title': 'tpl_call_status',
2136    //                 'property': {
2137    //                     'users': app.helpers.getUsersStatus()
2138    //                 }
2139    //             });
2140    //         }
2141
2142    //         if (_.isEmpty(app.currentSession) || isCallEnded) {
2143    //             if (call.callTimer) {
2144    //                 $('#timer').addClass('invisible');
2145    //                 clearInterval(call.callTimer);
2146    //                 call.callTimer = null;
2147    //                 call.callTime = 0;
2148    //                 app.helpers.network = {};
2149    //             }
2150    //         }
2151    //     }
2152
2153    //     if (session.opponentsIDs.length > 1 && session.opponentsIDs.length < 4) {
2154    //         $("#main_video").css("display", "none");
2155    //         $(".caller__frames").css({ "width": "51%", "height": "50%", "border": "none", "position": "absolute", "bottom": "0", "right": "0", "padding": "2%", "border-bottom": "0", "border-radius": "6px 6px 0 0", "overflow": "hidden", "background": "#777777" });
2156    //     } else if (ession.opponentsIDs.length > 4 && session.opponentsIDs.length < 5) {
2157    //         $("#main_video").css("display", "none");
2158    //         $(".caller__frames").css({ "width": "15%", "border": "1px solid #555555", "position": "absolute", "bottom": "0", "right": "0", "padding": "0", "border-bottom": "0", "border-radius": "6px 6px 0 0", "overflow": "hidden", "background": "#777777" });
2159    //     } else if (session.opponentsIDs.length > 2 && session.opponentsIDs.length < 4) {
2160    //         $("#main_video").css("display", "none");
2161    //         $(".caller__frames").css({ "width": "51%", "height": "50%", "border": "none", "position": "absolute", "bottom": "0", "right": "0", "padding": "2%", "border-bottom": "0", "border-radius": "6px 6px 0 0", "overflow": "hidden", "background": "#777777" });
2162    //     }
2163    // };
2164
2165    QB.webrtc.onDevicesChangeListener = function onDevicesChangeListeners() {
2166        //alert("lst-12");            
2167        fillMediaSelects().then(switchMediaTracks);
2168    };
2169
2170    // private functions
2171    function closeConn(userId) {
2172        //alert("lst-13");            
2173        if (recorder && recorderTimeoutID) {
2174            recorder.stop();
2175        }
2176        app.helpers.notifyIfUserLeaveCall(app.currentSession, userId, 'disconnected', 'Disconnected');
2177        app.currentSession.closeConnection(userId);
2178    }
2179
2180    function showMediaDevices(kind) {
2181        //alert("lst-14");            
2182        return new Promise(function (resolve, reject) {
2183            QB.webrtc.getMediaDevices(kind).then(function (devices) {
2184                var isVideoInput = (kind === 'videoinput'),
2185                    $select = isVideoInput ? $(ui.videoSourceFilter) : $(ui.audioSourceFilter);
2186                $select.empty();
2187                if (devices.length) {
2188                    for (var i = 0; i !== devices.length; ++i) {
2189                        var deviceInfo = devices[i],
2190                            option = document.createElement('option');
2191                        option.value = deviceInfo.deviceId;
2192                        if (deviceInfo.kind === kind) {
2193                            option.text = deviceInfo.label || (isVideoInput ? 'Camera ' : 'Mic ') + (i + 1);
2194                            $select.append(option);
2195                        }
2196                    }
2197                    //alert('your are herer');
2198                    $('.j-media_sources').removeClass('invisible');
2199                } else {
2200                    //alert('your are herer elseeee');
2201                    $('.j-media_sources').addClass('invisible');
2202                }
2203                resolve();
2204            }).catch(function (error) {
2205                //alert('your are herer catch errror');
2206                console.warn('getMediaDevices', error);
2207                reject();
2208            });
2209        });
2210    }
2211
2212    function fillMediaSelects() {
2213        //alert("lst-15");            
2214        return new Promise(function (resolve, reject) {
2215            navigator.mediaDevices.getUserMedia({
2216                audio: true,
2217                video: true
2218            }).then(function (stream) {
2219                showMediaDevices('videoinput').then(function () {
2220                    return showMediaDevices('audioinput');
2221                }).then(function () {
2222                    stream.getTracks().forEach(function (track) {
2223                        track.stop();
2224                    });
2225                    resolve();
2226                });
2227            }).catch(function (error) {
2228                console.warn('Video devices were shown without names (getUserMedia error)', error);
2229                showMediaDevices('videoinput').then(function () {
2230                    return showMediaDevices('audioinput');
2231                }).then(function () {
2232                    resolve();
2233                });
2234            });
2235        });
2236    }
2237
2238    function switchMediaTracks() {
2239        // alert("lst-16");       
2240        var localVideo = document.getElementById('localVideo');
2241        if (localVideo) {
2242
2243            if ((typeof localVideo == "object" && !localVideo.srcObject) || !app.currentSession) {
2244                return true;
2245            }
2246        }
2247
2248        var audioDeviceId = $(ui.audioSourceFilter).val() ? $(ui.audioSourceFilter).val() : undefined,
2249            videoDeviceId = $(ui.videoSourceFilter).val() ? { exact: $(ui.videoSourceFilter).val() } : undefined,
2250            deviceIds = {
2251                audio: audioDeviceId,
2252                video: videoDeviceId
2253            };
2254
2255        var callback = function (err, stream) {
2256            if (err || (!stream.getAudioTracks().length && !stream.getVideoTracks().length)) {
2257                app.currentSession.stop({});
2258
2259                app.helpers.stateBoard.update({
2260                    'title': 'tpl_device_not_found',
2261                    'isError': 'qb-error',
2262                    'property': {
2263                        'name': app.caller.full_name
2264                    }
2265                });
2266            }
2267        };
2268
2269        if (app.currentSession) {
2270            app.currentSession.switchMediaTracks(deviceIds, callback);
2271
2272        }
2273    }
2274
2275    function opponents_close(session, userId, extension) {
2276        if (session.opponentsIDs.length > 1) {
2277            //alert(initiatorID+"=stage-1="+userId);
2278            var opID = session.opponentsIDs;
2279            opID.forEach(function (a, i) {
2280                $(".income_call").modal('hide')[i];
2281                // $("#myModalAV").modal('hide')[i];
2282                // console.log(opID.length);
2283                document.getElementById(sounds.rington).pause();
2284                opID[i] = Number(a);
2285            });
2286            // console.log(opID);
2287
2288            var index = opID.indexOf(userId);
2289            if (index > -1) {
2290                opID.splice(index, 1);
2291            }
2292            // console.log('[session.opponentsIDs==result]',opID);
2293            if (initiatorID === userId) {
2294                if (!_.isEmpty(app.currentSession)) {
2295                    if (recorder && recorderTimeoutID) {
2296                        recorder.stop();
2297                    }
2298                    app.currentSession.stop({});
2299                    app.currentSession.closed({});
2300                    app.currentSession = {};
2301                    app.helpers.stateBoard.update({
2302                        'title': 'tpl_default',
2303                        'property': {
2304                            'name': app.caller.full_name,
2305                        }
2306                    });
2307                    $(".g_2.hangup").trigger("click");
2308                    $(".g_2").trigger("click");
2309
2310                    /*app.helpers.setFooterPosition();*/
2311                    return false;
2312                }
2313            }
2314            if (opID.length < 1) {
2315                //$(".g_2").trigger("click");
2316                // $(".g_1").trigger("click");
2317                if (!_.isEmpty(app.currentSession)) {
2318                    if (recorder && recorderTimeoutID) {
2319                        recorder.stop();
2320                    }
2321                    app.currentSession.stop({});
2322                    app.currentSession.closed({});
2323                    app.currentSession = {};
2324                    app.helpers.stateBoard.update({
2325                        'title': 'tpl_default',
2326                        'property': {
2327                            'name': app.caller.full_name,
2328                        }
2329                    });
2330                    $(".g_2.hangup").trigger("click");
2331                    $(".g_2").trigger("click");
2332                    $(".g_1.hangup").trigger("click");
2333                    $(".g_1").trigger("click");
2334                    /*app.helpers.setFooterPosition();*/
2335                    return false;
2336                }
2337            }
2338        }
2339    }
2340});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.