| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 | /* global $, config, getRoomName, loggingConfig, JitsiMeetJS */
/* application specific logic */
const logger = require("jitsi-meet-logger").getLogger(__filename);
import "babel-polyfill";
import "jquery";
import "jquery-contextmenu";
import "jquery-ui";
import "strophe";
import "strophe-disco";
import "strophe-caps";
import "jQuery-Impromptu";
import "autosize";
import 'aui';
import 'aui-experimental';
import 'aui-css';
import 'aui-experimental-css';
window.toastr = require("toastr");
const Logger = require("jitsi-meet-logger");
const LogCollector = Logger.LogCollector;
import URLProcessor from "./modules/config/URLProcessor";
import RoomnameGenerator from './modules/util/RoomnameGenerator';
import UI from "./modules/UI/UI";
import settings from "./modules/settings/Settings";
import conference from './conference';
import ConferenceUrl from './modules/URL/ConferenceUrl';
import API from './modules/API/API';
import UIEvents from './service/UI/UIEvents';
import getTokenData from "./modules/tokendata/TokenData";
import translation from "./modules/translation/translation";
const ConferenceEvents = JitsiMeetJS.events.conference;
/**
 * Tries to push history state with the following parameters:
 * 'VideoChat', `Room: ${roomName}`, URL. If fail, prints the error and returns
 * it.
 */
function pushHistoryState(roomName, URL) {
    try {
        window.history.pushState(
            'VideoChat', `Room: ${roomName}`, URL
        );
    } catch (e) {
        logger.warn("Push history state failed with parameters:",
            'VideoChat', `Room: ${roomName}`, URL, e);
        return e;
    }
    return null;
}
/**
 * Replaces current history state(replaces the URL displayed by the browser).
 * @param {string} newUrl the URL string which is to be displayed by the browser
 * to the user.
 */
function replaceHistoryState (newUrl) {
    if (window.history
        && typeof window.history.replaceState === 'function') {
        window.history.replaceState({}, document.title, newUrl);
    }
}
/**
 * Builds and returns the room name.
 */
function buildRoomName () {
    let roomName = getRoomName();
    if(!roomName) {
        let word = RoomnameGenerator.generateRoomWithoutSeparator();
        roomName = word.toLowerCase();
        let historyURL = window.location.href + word;
        //Trying to push state with current URL + roomName
        pushHistoryState(word, historyURL);
    }
    return roomName;
}
/**
 * Adjusts the logging levels.
 * @private
 */
function configureLoggingLevels () {
    // NOTE The library Logger is separated from the app loggers, so the levels
    // have to be set in two places
    // Set default logging level
    const defaultLogLevel
        = loggingConfig.defaultLogLevel || JitsiMeetJS.logLevels.TRACE;
    Logger.setLogLevel(defaultLogLevel);
    JitsiMeetJS.setLogLevel(defaultLogLevel);
    // NOTE console was used on purpose here to go around the logging
    // and always print the default logging level to the console
    console.info("Default logging level set to: " + defaultLogLevel);
    // Set log level for each logger
    if (loggingConfig) {
        Object.keys(loggingConfig).forEach(function(loggerName) {
            if ('defaultLogLevel' !== loggerName) {
                const level = loggingConfig[loggerName];
                Logger.setLogLevelById(level, loggerName);
                JitsiMeetJS.setLogLevelById(level, loggerName);
            }
        });
    }
}
const APP = {
    // Used by do_external_connect.js if we receive the attach data after
    // connect was already executed. status property can be "initialized",
    // "ready" or "connecting". We are interested in "ready" status only which
    // means that connect was executed but we have to wait for the attach data.
    // In status "ready" handler property will be set to a function that will
    // finish the connect process when the attach data or error is received.
    connect: {
        status: "initialized",
        handler: null
    },
    // Used for automated performance tests
    connectionTimes: {
        "index.loaded": window.indexLoadedTime
    },
    UI,
    settings,
    conference,
    translation,
    /**
     * The log collector which captures JS console logs for this app.
     * @type {LogCollector}
     */
    logCollector: null,
    /**
     * Indicates if the log collector has been started (it will not be started
     * if the welcome page is displayed).
     */
    logCollectorStarted : false,
    /**
     * After the APP has been initialized provides utility methods for dealing
     * with the conference room URL(address).
     * @type ConferenceUrl
     */
    ConferenceUrl : null,
    connection: null,
    API,
    init () {
        this.initLogging();
        this.keyboardshortcut =
            require("./modules/keyboardshortcut/keyboardshortcut");
        this.configFetch = require("./modules/config/HttpConfigFetch");
        this.tokenData = getTokenData();
    },
    initLogging () {
        // Adjust logging level
        configureLoggingLevels();
        // Start the LogCollector and register it as the global log transport
        if (!this.logCollector) {
            this.logCollector = new LogCollector({
                storeLogs: (logJSON) => {
                    // Try catch was used, because there are many variables
                    // on the way that could be uninitialized if the storeLogs
                    // attempt would be made very early (which is unlikely)
                    try {
                        // Currently it makes sense to store the log only
                        // if CallStats is enabled
                        if (APP.logCollectorStarted
                                && APP.conference
                                && APP.conference.isCallstatsEnabled()) {
                            APP.conference.logJSON(logJSON);
                        }
                    } catch (error) {
                        // NOTE console is intentional here
                        console.error(
                            "Failed to store the logs: ", logJSON, error);
                    }
                }
            });
            Logger.addGlobalTransport(this.logCollector);
            JitsiMeetJS.addGlobalLogTransport(this.logCollector);
        }
    }
};
/**
 * If JWT token data it will be used for local user settings
 */
function setTokenData() {
    let localUser = APP.tokenData.caller;
    if(localUser) {
        APP.settings.setEmail((localUser.getEmail() || "").trim(), true);
        APP.settings.setAvatarUrl((localUser.getAvatarUrl() || "").trim());
        APP.settings.setDisplayName((localUser.getName() || "").trim(), true);
    }
}
function init() {
    setTokenData();
    // Initialize the conference URL handler
    APP.ConferenceUrl = new ConferenceUrl(window.location);
    // Clean up the URL displayed by the browser
    replaceHistoryState(APP.ConferenceUrl.getInviteUrl());
    var isUIReady = APP.UI.start();
    if (isUIReady) {
        // Start the LogCollector's periodic "store logs" task only if we're in
        // the conference and not on the welcome page.
        APP.logCollector.start();
        APP.logCollectorStarted = true;
        APP.conference.init({roomName: buildRoomName()}).then(function () {
            // Will flush the logs, before the stats are disposed
            if (APP.logCollector) {
                APP.conference.addConferenceListener(
                    ConferenceEvents.BEFORE_STATISTICS_DISPOSED,
                    () => {
                        if (APP.logCollector) {
                            APP.logCollector.flush();
                        }
                    }
                );
            }
            APP.UI.initConference();
            APP.UI.addListener(UIEvents.LANG_CHANGED, function (language) {
                APP.translation.setLanguage(language);
                APP.settings.setLanguage(language);
            });
            APP.keyboardshortcut.init();
        }).catch(function (err) {
            APP.UI.hideRingOverLay();
            APP.API.notifyConferenceLeft(APP.conference.roomName);
            logger.error(err);
        });
    }
}
/**
 * If we have an HTTP endpoint for getting config.json configured we're going to
 * read it and override properties from config.js and interfaceConfig.js.
 * If there is no endpoint we'll just continue with initialization.
 * Keep in mind that if the endpoint has been configured and we fail to obtain
 * the config for any reason then the conference won't start and error message
 * will be displayed to the user.
 */
function obtainConfigAndInit() {
    let roomName = APP.conference.roomName;
    if (config.configLocation) {
        APP.configFetch.obtainConfig(
            config.configLocation, roomName,
            // Get config result callback
            function(success, error) {
                if (success) {
                    var now = APP.connectionTimes["configuration.fetched"] =
                        window.performance.now();
                    logger.log("(TIME) configuration fetched:\t", now);
                    init();
                } else {
                    // Show obtain config error,
                    // pass the error object for report
                    APP.UI.messageHandler.openReportDialog(
                        null, "dialog.connectError", error);
                }
            });
    } else {
        require("./modules/config/BoshAddressChoice").chooseAddress(
            config, roomName);
        init();
    }
}
$(document).ready(function () {
    var now = APP.connectionTimes["document.ready"] = window.performance.now();
    logger.log("(TIME) document ready:\t", now);
    URLProcessor.setConfigParametersFromUrl();
    APP.init();
    APP.translation.init(settings.getLanguage());
    APP.API.init(APP.tokenData.externalAPISettings);
    obtainConfigAndInit();
});
$(window).bind('beforeunload', function () {
    // Stop the LogCollector
    if (APP.logCollectorStarted) {
        APP.logCollector.stop();
        APP.logCollectorStarted = false;
    }
    APP.API.dispose();
});
module.exports = APP;
 |