You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Toolbar.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /* global APP, $, config, interfaceConfig */
  2. /* jshint -W101 */
  3. var messageHandler = require("../util/MessageHandler");
  4. var UIUtil = require("../util/UIUtil");
  5. var AnalyticsAdapter = require("../../statistics/AnalyticsAdapter");
  6. var Feedback = require("../Feedback");
  7. var UIEvents = require("../../../service/UI/UIEvents");
  8. var roomUrl = null;
  9. var recordingToaster = null;
  10. var emitter = null;
  11. /**
  12. * Opens the invite link dialog.
  13. */
  14. function openLinkDialog () {
  15. var inviteAttributes;
  16. if (roomUrl === null) {
  17. inviteAttributes = 'data-i18n="[value]roomUrlDefaultMsg" value="' +
  18. APP.translation.translateString("roomUrlDefaultMsg") + '"';
  19. } else {
  20. inviteAttributes = "value=\"" + encodeURI(roomUrl) + "\"";
  21. }
  22. messageHandler.openTwoButtonDialog(
  23. "dialog.shareLink", null, null,
  24. `<input id="inviteLinkRef" type="text" ${inviteAttributes} onclick="this.select();" readonly>`,
  25. false, "dialog.Invite",
  26. function (e, v) {
  27. if (v && roomUrl) {
  28. emitter.emit(UIEvents.USER_INVITED, roomUrl);
  29. }
  30. },
  31. function (event) {
  32. if (roomUrl) {
  33. document.getElementById('inviteLinkRef').select();
  34. } else {
  35. if (event && event.target) {
  36. $(event.target).find('button[value=true]').prop('disabled', true);
  37. }
  38. }
  39. }
  40. );
  41. }
  42. // Sets the state of the recording button
  43. function setRecordingButtonState (recordingState) {
  44. let selector = $('#toolbar_button_record');
  45. if (recordingState === 'on') {
  46. selector.removeClass("icon-recEnable");
  47. selector.addClass("icon-recEnable active");
  48. $("#largeVideo").toggleClass("videoMessageFilter", true);
  49. let recordOnKey = "recording.on";
  50. $('#videoConnectionMessage').attr("data-i18n", recordOnKey);
  51. $('#videoConnectionMessage').text(APP.translation.translateString(recordOnKey));
  52. setTimeout(function(){
  53. $("#largeVideo").toggleClass("videoMessageFilter", false);
  54. $('#videoConnectionMessage').css({display: "none"});
  55. }, 1500);
  56. recordingToaster = messageHandler.notify(
  57. null, "recording.toaster", null,
  58. null, null,
  59. {timeOut: 0, closeButton: null, tapToDismiss: false}
  60. );
  61. } else if (recordingState === 'off') {
  62. selector.removeClass("icon-recEnable active");
  63. selector.addClass("icon-recEnable");
  64. $("#largeVideo").toggleClass("videoMessageFilter", false);
  65. $('#videoConnectionMessage').css({display: "none"});
  66. if (recordingToaster) {
  67. messageHandler.remove(recordingToaster);
  68. }
  69. } else if (recordingState === 'pending') {
  70. selector.removeClass("icon-recEnable active");
  71. selector.addClass("icon-recEnable");
  72. $("#largeVideo").toggleClass("videoMessageFilter", true);
  73. let recordPendingKey = "recording.pending";
  74. $('#videoConnectionMessage').attr("data-i18n", recordPendingKey);
  75. $('#videoConnectionMessage').text(APP.translation.translateString(recordPendingKey));
  76. $('#videoConnectionMessage').css({display: "block"});
  77. }
  78. }
  79. const buttonHandlers = {
  80. "toolbar_button_mute": function () {
  81. if (APP.conference.audioMuted) {
  82. AnalyticsAdapter.sendEvent('toolbar.audio.unmuted');
  83. emitter.emit(UIEvents.AUDIO_MUTED, false);
  84. } else {
  85. AnalyticsAdapter.sendEvent('toolbar.audio.muted');
  86. emitter.emit(UIEvents.AUDIO_MUTED, true);
  87. }
  88. },
  89. "toolbar_button_camera": function () {
  90. if (APP.conference.videoMuted) {
  91. AnalyticsAdapter.sendEvent('toolbar.video.enabled');
  92. emitter.emit(UIEvents.VIDEO_MUTED, false);
  93. } else {
  94. AnalyticsAdapter.sendEvent('toolbar.video.disabled');
  95. emitter.emit(UIEvents.VIDEO_MUTED, true);
  96. }
  97. },
  98. "toolbar_button_record": function () {
  99. AnalyticsAdapter.sendEvent('toolbar.recording.toggled');
  100. toggleRecording();
  101. },
  102. "toolbar_button_security": function () {
  103. emitter.emit(UIEvents.ROOM_LOCK_CLICKED);
  104. },
  105. "toolbar_button_link": function () {
  106. AnalyticsAdapter.sendEvent('toolbar.invite.clicked');
  107. openLinkDialog();
  108. },
  109. "toolbar_button_chat": function () {
  110. AnalyticsAdapter.sendEvent('toolbar.chat.toggled');
  111. emitter.emit(UIEvents.TOGGLE_CHAT);
  112. },
  113. "toolbar_button_prezi": function () {
  114. AnalyticsAdapter.sendEvent('toolbar.prezi.clicked');
  115. emitter.emit(UIEvents.PREZI_CLICKED);
  116. },
  117. "toolbar_button_etherpad": function () {
  118. AnalyticsAdapter.sendEvent('toolbar.etherpad.clicked');
  119. emitter.emit(UIEvents.ETHERPAD_CLICKED);
  120. },
  121. "toolbar_button_desktopsharing": function () {
  122. if (APP.desktopsharing.isUsingScreenStream) {
  123. AnalyticsAdapter.sendEvent('toolbar.screen.disabled');
  124. } else {
  125. AnalyticsAdapter.sendEvent('toolbar.screen.enabled');
  126. }
  127. APP.desktopsharing.toggleScreenSharing();
  128. },
  129. "toolbar_button_fullScreen": function() {
  130. AnalyticsAdapter.sendEvent('toolbar.fullscreen.enabled');
  131. UIUtil.buttonClick("#toolbar_button_fullScreen", "icon-full-screen icon-exit-full-screen");
  132. emitter.emit(UIEvents.FULLSCREEN_TOGGLE);
  133. },
  134. "toolbar_button_sip": function () {
  135. AnalyticsAdapter.sendEvent('toolbar.sip.clicked');
  136. callSipButtonClicked();
  137. },
  138. "toolbar_button_dialpad": function () {
  139. AnalyticsAdapter.sendEvent('toolbar.sip.dialpad.clicked');
  140. dialpadButtonClicked();
  141. },
  142. "toolbar_button_settings": function () {
  143. AnalyticsAdapter.sendEvent('toolbar.settings.toggled');
  144. emitter.emit(UIEvents.TOGGLE_SETTINGS);
  145. },
  146. "toolbar_button_hangup": function () {
  147. AnalyticsAdapter.sendEvent('toolbar.hangup');
  148. hangup();
  149. },
  150. "toolbar_button_login": function () {
  151. AnalyticsAdapter.sendEvent('toolbar.authenticate.login.clicked');
  152. emitter.emit(UIEvents.AUTH_CLICKED);
  153. },
  154. "toolbar_button_logout": function () {
  155. AnalyticsAdapter.sendEvent('toolbar.authenticate.logout.clicked');
  156. // Ask for confirmation
  157. messageHandler.openTwoButtonDialog(
  158. "dialog.logoutTitle",
  159. null,
  160. "dialog.logoutQuestion",
  161. null,
  162. false,
  163. "dialog.Yes",
  164. function (evt, yes) {
  165. if (yes) {
  166. APP.xmpp.logout(function (url) {
  167. if (url) {
  168. window.location.href = url;
  169. } else {
  170. hangup();
  171. }
  172. });
  173. }
  174. });
  175. }
  176. };
  177. var defaultToolbarButtons = {
  178. 'microphone': '#toolbar_button_mute',
  179. 'camera': '#toolbar_button_camera',
  180. 'desktop': '#toolbar_button_desktopsharing',
  181. 'security': '#toolbar_button_security',
  182. 'invite': '#toolbar_button_link',
  183. 'chat': '#toolbar_button_chat',
  184. 'prezi': '#toolbar_button_prezi',
  185. 'etherpad': '#toolbar_button_etherpad',
  186. 'fullscreen': '#toolbar_button_fullScreen',
  187. 'settings': '#toolbar_button_settings',
  188. 'hangup': '#toolbar_button_hangup'
  189. };
  190. /**
  191. * Hangs up this call.
  192. */
  193. function hangup() {
  194. var conferenceDispose = function () {
  195. APP.xmpp.disposeConference();
  196. if (config.enableWelcomePage) {
  197. setTimeout(function() {
  198. window.localStorage.welcomePageDisabled = false;
  199. window.location.pathname = "/";
  200. }, 3000);
  201. }
  202. };
  203. if (Feedback.isEnabled()) {
  204. // If the user has already entered feedback, we'll show the window and
  205. // immidiately start the conference dispose timeout.
  206. if (Feedback.feedbackScore > 0) {
  207. Feedback.openFeedbackWindow();
  208. conferenceDispose();
  209. }
  210. // Otherwise we'll wait for user's feedback.
  211. else
  212. Feedback.openFeedbackWindow(conferenceDispose);
  213. }
  214. else {
  215. conferenceDispose();
  216. // If the feedback functionality isn't enabled we show a thank you
  217. // dialog.
  218. messageHandler.openMessageDialog(null, null, null,
  219. APP.translation.translateString("dialog.thankYou",
  220. {appName:interfaceConfig.APP_NAME}));
  221. }
  222. }
  223. /**
  224. * Starts or stops the recording for the conference.
  225. */
  226. function toggleRecording(predefinedToken) {
  227. APP.xmpp.toggleRecording(function (callback) {
  228. if (predefinedToken) {
  229. callback(UIUtil.escapeHtml(predefinedToken));
  230. return;
  231. }
  232. var msg = APP.translation.generateTranslationHTML(
  233. "dialog.recordingToken");
  234. var token = APP.translation.translateString("dialog.token");
  235. messageHandler.openTwoButtonDialog(null, null, null,
  236. '<h2>' + msg + '</h2>' +
  237. '<input name="recordingToken" type="text" ' +
  238. ' data-i18n="[placeholder]dialog.token" ' +
  239. 'placeholder="' + token + '" autofocus>',
  240. false,
  241. "dialog.Save",
  242. function (e, v, m, f) {
  243. if (v) {
  244. var token = f.recordingToken;
  245. if (token) {
  246. callback(UIUtil.escapeHtml(token));
  247. }
  248. }
  249. },
  250. null,
  251. function () { },
  252. ':input:first'
  253. );
  254. }, setRecordingButtonState);
  255. }
  256. function dialpadButtonClicked() {
  257. //TODO show the dialpad box
  258. }
  259. function callSipButtonClicked() {
  260. let defaultNumber = config.defaultSipNumber
  261. ? config.defaultSipNumber
  262. : '';
  263. let sipMsg = APP.translation.generateTranslationHTML("dialog.sipMsg");
  264. messageHandler.openTwoButtonDialog(
  265. null, null, null,
  266. `<h2>${sipMsg}</h2>
  267. <input name="sipNumber" type="text" value="${defaultNumber}" autofocus>`,
  268. false, "dialog.Dial",
  269. function (e, v, m, f) {
  270. if (v) {
  271. var numberInput = f.sipNumber;
  272. if (numberInput) {
  273. APP.xmpp.dial(numberInput, 'fromnumber', APP.conference.roomName, APP.conference.sharedKey);
  274. }
  275. }
  276. },
  277. null, null, ':input:first'
  278. );
  279. }
  280. const Toolbar = {
  281. init (eventEmitter) {
  282. emitter = eventEmitter;
  283. UIUtil.hideDisabledButtons(defaultToolbarButtons);
  284. for(var k in buttonHandlers)
  285. $("#" + k).click(buttonHandlers[k]);
  286. },
  287. /**
  288. * Updates the room invite url.
  289. */
  290. updateRoomUrl (newRoomUrl) {
  291. roomUrl = newRoomUrl;
  292. // If the invite dialog has been already opened we update the information.
  293. var inviteLink = document.getElementById('inviteLinkRef');
  294. if (inviteLink) {
  295. inviteLink.value = roomUrl;
  296. inviteLink.select();
  297. $('#inviteLinkRef').parent()
  298. .find('button[value=true]').prop('disabled', false);
  299. }
  300. },
  301. /**
  302. * Disables and enables some of the buttons.
  303. */
  304. setupButtonsFromConfig () {
  305. if (UIUtil.isButtonEnabled('prezi')) {
  306. $("#toolbar_button_prezi").css({display: "none"});
  307. }
  308. },
  309. /**
  310. * Unlocks the lock button state.
  311. */
  312. unlockLockButton () {
  313. if ($("#toolbar_button_security").hasClass("icon-security-locked"))
  314. UIUtil.buttonClick("#toolbar_button_security", "icon-security icon-security-locked");
  315. },
  316. /**
  317. * Updates the lock button state to locked.
  318. */
  319. lockLockButton () {
  320. if ($("#toolbar_button_security").hasClass("icon-security"))
  321. UIUtil.buttonClick("#toolbar_button_security", "icon-security icon-security-locked");
  322. },
  323. /**
  324. * Shows or hides authentication button
  325. * @param show <tt>true</tt> to show or <tt>false</tt> to hide
  326. */
  327. showAuthenticateButton (show) {
  328. if (UIUtil.isButtonEnabled('authentication') && show) {
  329. $('#authentication').css({display: "inline"});
  330. }
  331. else {
  332. $('#authentication').css({display: "none"});
  333. }
  334. },
  335. // Shows or hides the 'recording' button.
  336. showRecordingButton (show) {
  337. if (UIUtil.isButtonEnabled('recording') && show) {
  338. $('#toolbar_button_record').css({display: "inline-block"});
  339. }
  340. else {
  341. $('#toolbar_button_record').css({display: "none"});
  342. }
  343. },
  344. // checks whether recording is enabled and whether we have params
  345. // to start automatically recording
  346. checkAutoRecord () {
  347. if (UIUtil.isButtonEnabled('recording') && config.autoRecord) {
  348. toggleRecording(config.autoRecordToken);
  349. }
  350. },
  351. // checks whether desktop sharing is enabled and whether
  352. // we have params to start automatically sharing
  353. checkAutoEnableDesktopSharing () {
  354. if (UIUtil.isButtonEnabled('desktop')
  355. && config.autoEnableDesktopSharing) {
  356. APP.desktopsharing.toggleScreenSharing();
  357. }
  358. },
  359. // Shows or hides SIP calls button
  360. showSipCallButton (show) {
  361. if (APP.xmpp.isSipGatewayEnabled() && UIUtil.isButtonEnabled('sip') && show) {
  362. $('#toolbar_button_sip').css({display: "inline-block"});
  363. } else {
  364. $('#toolbar_button_sip').css({display: "none"});
  365. }
  366. },
  367. // Shows or hides the dialpad button
  368. showDialPadButton (show) {
  369. if (UIUtil.isButtonEnabled('dialpad') && show) {
  370. $('#toolbar_button_dialpad').css({display: "inline-block"});
  371. } else {
  372. $('#toolbar_button_dialpad').css({display: "none"});
  373. }
  374. },
  375. /**
  376. * Displays user authenticated identity name(login).
  377. * @param authIdentity identity name to be displayed.
  378. */
  379. setAuthenticatedIdentity (authIdentity) {
  380. if (authIdentity) {
  381. var selector = $('#toolbar_auth_identity');
  382. selector.css({display: "list-item"});
  383. selector.text(authIdentity);
  384. } else {
  385. $('#toolbar_auth_identity').css({display: "none"});
  386. }
  387. },
  388. /**
  389. * Shows/hides login button.
  390. * @param show <tt>true</tt> to show
  391. */
  392. showLoginButton (show) {
  393. if (UIUtil.isButtonEnabled('authentication') && show) {
  394. $('#toolbar_button_login').css({display: "list-item"});
  395. } else {
  396. $('#toolbar_button_login').css({display: "none"});
  397. }
  398. },
  399. /**
  400. * Shows/hides logout button.
  401. * @param show <tt>true</tt> to show
  402. */
  403. showLogoutButton (show) {
  404. if (UIUtil.isButtonEnabled('authentication') && show) {
  405. $('#toolbar_button_logout').css({display: "list-item"});
  406. } else {
  407. $('#toolbar_button_logout').css({display: "none"});
  408. }
  409. },
  410. /**
  411. * Sets the state of the button. The button has blue glow if desktop
  412. * streaming is active.
  413. * @param active the state of the desktop streaming.
  414. */
  415. changeDesktopSharingButtonState (active) {
  416. var button = $("#toolbar_button_desktopsharing");
  417. if (active) {
  418. button.addClass("glow");
  419. } else {
  420. button.removeClass("glow");
  421. }
  422. }
  423. };
  424. export default Toolbar;