您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

app.js 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /* global $, config, getRoomName, loggingConfig, JitsiMeetJS */
  2. /* application specific logic */
  3. const logger = require("jitsi-meet-logger").getLogger(__filename);
  4. import "babel-polyfill";
  5. import "jquery";
  6. import "jquery-contextmenu";
  7. import "jquery-ui";
  8. import "strophe";
  9. import "strophe-disco";
  10. import "strophe-caps";
  11. import "jQuery-Impromptu";
  12. import "autosize";
  13. import 'aui';
  14. import 'aui-experimental';
  15. import 'aui-css';
  16. import 'aui-experimental-css';
  17. window.toastr = require("toastr");
  18. const Logger = require("jitsi-meet-logger");
  19. const LogCollector = Logger.LogCollector;
  20. import URLProcessor from "./modules/config/URLProcessor";
  21. import RoomnameGenerator from './modules/util/RoomnameGenerator';
  22. import UI from "./modules/UI/UI";
  23. import settings from "./modules/settings/Settings";
  24. import conference from './conference';
  25. import ConferenceUrl from './modules/URL/ConferenceUrl';
  26. import API from './modules/API/API';
  27. import UIEvents from './service/UI/UIEvents';
  28. import getTokenData from "./modules/tokendata/TokenData";
  29. import translation from "./modules/translation/translation";
  30. const ConferenceEvents = JitsiMeetJS.events.conference;
  31. /**
  32. * Tries to push history state with the following parameters:
  33. * 'VideoChat', `Room: ${roomName}`, URL. If fail, prints the error and returns
  34. * it.
  35. */
  36. function pushHistoryState(roomName, URL) {
  37. try {
  38. window.history.pushState(
  39. 'VideoChat', `Room: ${roomName}`, URL
  40. );
  41. } catch (e) {
  42. logger.warn("Push history state failed with parameters:",
  43. 'VideoChat', `Room: ${roomName}`, URL, e);
  44. return e;
  45. }
  46. return null;
  47. }
  48. /**
  49. * Replaces current history state(replaces the URL displayed by the browser).
  50. * @param {string} newUrl the URL string which is to be displayed by the browser
  51. * to the user.
  52. */
  53. function replaceHistoryState (newUrl) {
  54. if (window.history
  55. && typeof window.history.replaceState === 'function') {
  56. window.history.replaceState({}, document.title, newUrl);
  57. }
  58. }
  59. /**
  60. * Builds and returns the room name.
  61. */
  62. function buildRoomName () {
  63. let roomName = getRoomName();
  64. if(!roomName) {
  65. let word = RoomnameGenerator.generateRoomWithoutSeparator();
  66. roomName = word.toLowerCase();
  67. let historyURL = window.location.href + word;
  68. //Trying to push state with current URL + roomName
  69. pushHistoryState(word, historyURL);
  70. }
  71. return roomName;
  72. }
  73. /**
  74. * Adjusts the logging levels.
  75. * @private
  76. */
  77. function configureLoggingLevels () {
  78. // NOTE The library Logger is separated from the app loggers, so the levels
  79. // have to be set in two places
  80. // Set default logging level
  81. const defaultLogLevel
  82. = loggingConfig.defaultLogLevel || JitsiMeetJS.logLevels.TRACE;
  83. Logger.setLogLevel(defaultLogLevel);
  84. JitsiMeetJS.setLogLevel(defaultLogLevel);
  85. // NOTE console was used on purpose here to go around the logging
  86. // and always print the default logging level to the console
  87. console.info("Default logging level set to: " + defaultLogLevel);
  88. // Set log level for each logger
  89. if (loggingConfig) {
  90. Object.keys(loggingConfig).forEach(function(loggerName) {
  91. if ('defaultLogLevel' !== loggerName) {
  92. const level = loggingConfig[loggerName];
  93. Logger.setLogLevelById(level, loggerName);
  94. JitsiMeetJS.setLogLevelById(level, loggerName);
  95. }
  96. });
  97. }
  98. }
  99. const APP = {
  100. // Used by do_external_connect.js if we receive the attach data after
  101. // connect was already executed. status property can be "initialized",
  102. // "ready" or "connecting". We are interested in "ready" status only which
  103. // means that connect was executed but we have to wait for the attach data.
  104. // In status "ready" handler property will be set to a function that will
  105. // finish the connect process when the attach data or error is received.
  106. connect: {
  107. status: "initialized",
  108. handler: null
  109. },
  110. // Used for automated performance tests
  111. connectionTimes: {
  112. "index.loaded": window.indexLoadedTime
  113. },
  114. UI,
  115. settings,
  116. conference,
  117. translation,
  118. /**
  119. * The log collector which captures JS console logs for this app.
  120. * @type {LogCollector}
  121. */
  122. logCollector: null,
  123. /**
  124. * Indicates if the log collector has been started (it will not be started
  125. * if the welcome page is displayed).
  126. */
  127. logCollectorStarted : false,
  128. /**
  129. * After the APP has been initialized provides utility methods for dealing
  130. * with the conference room URL(address).
  131. * @type ConferenceUrl
  132. */
  133. ConferenceUrl : null,
  134. connection: null,
  135. API,
  136. init () {
  137. this.initLogging();
  138. this.keyboardshortcut =
  139. require("./modules/keyboardshortcut/keyboardshortcut");
  140. this.configFetch = require("./modules/config/HttpConfigFetch");
  141. this.tokenData = getTokenData();
  142. },
  143. initLogging () {
  144. // Adjust logging level
  145. configureLoggingLevels();
  146. // Start the LogCollector and register it as the global log transport
  147. if (!this.logCollector) {
  148. this.logCollector = new LogCollector({
  149. storeLogs: (logJSON) => {
  150. // Try catch was used, because there are many variables
  151. // on the way that could be uninitialized if the storeLogs
  152. // attempt would be made very early (which is unlikely)
  153. try {
  154. // Currently it makes sense to store the log only
  155. // if CallStats is enabled
  156. if (APP.logCollectorStarted
  157. && APP.conference
  158. && APP.conference.isCallstatsEnabled()) {
  159. APP.conference.logJSON(logJSON);
  160. }
  161. } catch (error) {
  162. // NOTE console is intentional here
  163. console.error(
  164. "Failed to store the logs: ", logJSON, error);
  165. }
  166. }
  167. });
  168. Logger.addGlobalTransport(this.logCollector);
  169. JitsiMeetJS.addGlobalLogTransport(this.logCollector);
  170. }
  171. }
  172. };
  173. /**
  174. * If JWT token data it will be used for local user settings
  175. */
  176. function setTokenData() {
  177. let localUser = APP.tokenData.caller;
  178. if(localUser) {
  179. APP.settings.setEmail((localUser.getEmail() || "").trim(), true);
  180. APP.settings.setAvatarUrl((localUser.getAvatarUrl() || "").trim());
  181. APP.settings.setDisplayName((localUser.getName() || "").trim(), true);
  182. }
  183. }
  184. function init() {
  185. setTokenData();
  186. // Initialize the conference URL handler
  187. APP.ConferenceUrl = new ConferenceUrl(window.location);
  188. // Clean up the URL displayed by the browser
  189. replaceHistoryState(APP.ConferenceUrl.getInviteUrl());
  190. var isUIReady = APP.UI.start();
  191. if (isUIReady) {
  192. // Start the LogCollector's periodic "store logs" task only if we're in
  193. // the conference and not on the welcome page.
  194. APP.logCollector.start();
  195. APP.logCollectorStarted = true;
  196. APP.conference.init({roomName: buildRoomName()}).then(function () {
  197. // Will flush the logs, before the stats are disposed
  198. if (APP.logCollector) {
  199. APP.conference.addConferenceListener(
  200. ConferenceEvents.BEFORE_STATISTICS_DISPOSED,
  201. () => {
  202. if (APP.logCollector) {
  203. APP.logCollector.flush();
  204. }
  205. }
  206. );
  207. }
  208. APP.UI.initConference();
  209. APP.UI.addListener(UIEvents.LANG_CHANGED, function (language) {
  210. APP.translation.setLanguage(language);
  211. APP.settings.setLanguage(language);
  212. });
  213. APP.keyboardshortcut.init();
  214. }).catch(function (err) {
  215. APP.UI.hideRingOverLay();
  216. APP.API.notifyConferenceLeft(APP.conference.roomName);
  217. logger.error(err);
  218. });
  219. }
  220. }
  221. /**
  222. * If we have an HTTP endpoint for getting config.json configured we're going to
  223. * read it and override properties from config.js and interfaceConfig.js.
  224. * If there is no endpoint we'll just continue with initialization.
  225. * Keep in mind that if the endpoint has been configured and we fail to obtain
  226. * the config for any reason then the conference won't start and error message
  227. * will be displayed to the user.
  228. */
  229. function obtainConfigAndInit() {
  230. let roomName = APP.conference.roomName;
  231. if (config.configLocation) {
  232. APP.configFetch.obtainConfig(
  233. config.configLocation, roomName,
  234. // Get config result callback
  235. function(success, error) {
  236. if (success) {
  237. var now = APP.connectionTimes["configuration.fetched"] =
  238. window.performance.now();
  239. logger.log("(TIME) configuration fetched:\t", now);
  240. init();
  241. } else {
  242. // Show obtain config error,
  243. // pass the error object for report
  244. APP.UI.messageHandler.openReportDialog(
  245. null, "dialog.connectError", error);
  246. }
  247. });
  248. } else {
  249. require("./modules/config/BoshAddressChoice").chooseAddress(
  250. config, roomName);
  251. init();
  252. }
  253. }
  254. $(document).ready(function () {
  255. var now = APP.connectionTimes["document.ready"] = window.performance.now();
  256. logger.log("(TIME) document ready:\t", now);
  257. URLProcessor.setConfigParametersFromUrl();
  258. APP.init();
  259. APP.translation.init(settings.getLanguage());
  260. APP.API.init(APP.tokenData.externalAPISettings);
  261. obtainConfigAndInit();
  262. });
  263. $(window).bind('beforeunload', function () {
  264. // Stop the LogCollector
  265. if (APP.logCollectorStarted) {
  266. APP.logCollector.stop();
  267. APP.logCollectorStarted = false;
  268. }
  269. APP.API.dispose();
  270. });
  271. module.exports = APP;