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 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /*
  2. * Copyright @ 2015 Atlassian Pty Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* global APP,$, buttonClick, config, lockRoom,
  17. setSharedKey, Util */
  18. var messageHandler = require("../util/MessageHandler");
  19. var BottomToolbar = require("./BottomToolbar");
  20. var Prezi = require("../prezi/Prezi");
  21. var Etherpad = require("../etherpad/Etherpad");
  22. var PanelToggler = require("../side_pannels/SidePanelToggler");
  23. var Authentication = require("../authentication/Authentication");
  24. var UIUtil = require("../util/UIUtil");
  25. var AuthenticationEvents
  26. = require("../../../service/authentication/AuthenticationEvents");
  27. var roomUrl = null;
  28. var sharedKey = '';
  29. var UI = null;
  30. var buttonHandlers =
  31. {
  32. "toolbar_button_mute": function () {
  33. return APP.UI.toggleAudio();
  34. },
  35. "toolbar_button_camera": function () {
  36. return APP.UI.toggleVideo();
  37. },
  38. /*"toolbar_button_authentication": function () {
  39. return Toolbar.authenticateClicked();
  40. },*/
  41. "toolbar_button_record": function () {
  42. return toggleRecording();
  43. },
  44. "toolbar_button_security": function () {
  45. return Toolbar.openLockDialog();
  46. },
  47. "toolbar_button_link": function () {
  48. return Toolbar.openLinkDialog();
  49. },
  50. "toolbar_button_chat": function () {
  51. return BottomToolbar.toggleChat();
  52. },
  53. "toolbar_button_prezi": function () {
  54. return Prezi.openPreziDialog();
  55. },
  56. "toolbar_button_etherpad": function () {
  57. return Etherpad.toggleEtherpad(0);
  58. },
  59. "toolbar_button_desktopsharing": function () {
  60. return APP.desktopsharing.toggleScreenSharing();
  61. },
  62. "toolbar_button_fullScreen": function()
  63. {
  64. UIUtil.buttonClick("#fullScreen", "icon-full-screen icon-exit-full-screen");
  65. return Toolbar.toggleFullScreen();
  66. },
  67. "toolbar_button_sip": function () {
  68. return callSipButtonClicked();
  69. },
  70. "toolbar_button_dialpad": function () {
  71. return dialpadButtonClicked();
  72. },
  73. "toolbar_button_settings": function () {
  74. PanelToggler.toggleSettingsMenu();
  75. },
  76. "toolbar_button_hangup": function () {
  77. return hangup();
  78. },
  79. "toolbar_button_login": function () {
  80. Toolbar.authenticateClicked();
  81. },
  82. "toolbar_button_logout": function () {
  83. // Ask for confirmation
  84. messageHandler.openTwoButtonDialog(
  85. "dialog.logoutTitle",
  86. null,
  87. "dialog.logoutQuestion",
  88. null,
  89. false,
  90. "dialog.Yes",
  91. function (evt, yes) {
  92. if (yes) {
  93. APP.xmpp.logout(function (url) {
  94. if (url) {
  95. window.location.href = url;
  96. } else {
  97. hangup();
  98. }
  99. });
  100. }
  101. });
  102. }
  103. };
  104. function hangup() {
  105. APP.xmpp.disposeConference();
  106. if(config.enableWelcomePage)
  107. {
  108. setTimeout(function()
  109. {
  110. window.localStorage.welcomePageDisabled = false;
  111. window.location.pathname = "/";
  112. }, 10000);
  113. }
  114. var title = APP.translation.generateTranslatonHTML(
  115. "dialog.sessTerminated");
  116. var msg = APP.translation.generateTranslatonHTML(
  117. "dialog.hungUp");
  118. var button = APP.translation.generateTranslatonHTML(
  119. "dialog.joinAgain");
  120. var buttons = [];
  121. buttons.push({title: button, value: true});
  122. UI.messageHandler.openDialog(
  123. title,
  124. msg,
  125. true,
  126. buttons,
  127. function(event, value, message, formVals)
  128. {
  129. window.location.reload();
  130. return false;
  131. }
  132. );
  133. }
  134. /**
  135. * Starts or stops the recording for the conference.
  136. */
  137. function toggleRecording() {
  138. APP.xmpp.toggleRecording(function (callback) {
  139. var msg = APP.translation.generateTranslatonHTML(
  140. "dialog.recordingToken");
  141. var token = APP.translation.translateString("dialog.token");
  142. APP.UI.messageHandler.openTwoButtonDialog(null, null, null,
  143. '<h2>' + msg + '</h2>' +
  144. '<input name="recordingToken" type="text" ' +
  145. ' data-i18n="[placeholder]dialog.token" ' +
  146. 'placeholder="' + token + '" autofocus>',
  147. false,
  148. "dialog.Save",
  149. function (e, v, m, f) {
  150. if (v) {
  151. var token = f.recordingToken;
  152. if (token) {
  153. callback(UIUtil.escapeHtml(token));
  154. }
  155. }
  156. },
  157. null,
  158. function () { },
  159. ':input:first'
  160. );
  161. }, Toolbar.setRecordingButtonState, Toolbar.setRecordingButtonState);
  162. }
  163. /**
  164. * Locks / unlocks the room.
  165. */
  166. function lockRoom(lock) {
  167. var currentSharedKey = '';
  168. if (lock)
  169. currentSharedKey = sharedKey;
  170. APP.xmpp.lockRoom(currentSharedKey, function (res) {
  171. // password is required
  172. if (sharedKey)
  173. {
  174. console.log('set room password');
  175. Toolbar.lockLockButton();
  176. }
  177. else
  178. {
  179. console.log('removed room password');
  180. Toolbar.unlockLockButton();
  181. }
  182. }, function (err) {
  183. console.warn('setting password failed', err);
  184. messageHandler.showError("dialog.lockTitle",
  185. "dialog.lockMessage");
  186. Toolbar.setSharedKey('');
  187. }, function () {
  188. console.warn('room passwords not supported');
  189. messageHandler.showError("dialog.warning",
  190. "dialog.passwordNotSupported");
  191. Toolbar.setSharedKey('');
  192. });
  193. };
  194. /**
  195. * Invite participants to conference.
  196. */
  197. function inviteParticipants() {
  198. if (roomUrl === null)
  199. return;
  200. var sharedKeyText = "";
  201. if (sharedKey && sharedKey.length > 0) {
  202. sharedKeyText =
  203. APP.translation.translateString("email.sharedKey",
  204. {sharedKey: sharedKey});
  205. sharedKeyText = sharedKeyText.replace(/\n/g, "%0D%0A");
  206. }
  207. var supportedBrowsers = "Chromium, Google Chrome " +
  208. APP.translation.translateString("email.and") + " Opera";
  209. var conferenceName = roomUrl.substring(roomUrl.lastIndexOf('/') + 1);
  210. var subject = APP.translation.translateString("email.subject",
  211. {appName:interfaceConfig.APP_NAME, conferenceName: conferenceName});
  212. var body = APP.translation.translateString("email.body",
  213. {appName:interfaceConfig.APP_NAME, sharedKeyText: sharedKeyText,
  214. roomUrl: roomUrl, supportedBrowsers: supportedBrowsers});
  215. body = body.replace(/\n/g, "%0D%0A");
  216. if (window.localStorage.displayname) {
  217. body += "%0D%0A%0D%0A" + window.localStorage.displayname;
  218. }
  219. if (interfaceConfig.INVITATION_POWERED_BY) {
  220. body += "%0D%0A%0D%0A--%0D%0Apowered by jitsi.org";
  221. }
  222. window.open("mailto:?subject=" + subject + "&body=" + body, '_blank');
  223. }
  224. function dialpadButtonClicked()
  225. {
  226. //TODO show the dialpad window
  227. }
  228. function callSipButtonClicked()
  229. {
  230. var defaultNumber
  231. = config.defaultSipNumber ? config.defaultSipNumber : '';
  232. var sipMsg = APP.translation.generateTranslatonHTML(
  233. "dialog.sipMsg");
  234. messageHandler.openTwoButtonDialog(null, null, null,
  235. '<h2>' + sipMsg + '</h2>' +
  236. '<input name="sipNumber" type="text"' +
  237. ' value="' + defaultNumber + '" autofocus>',
  238. false,
  239. "dialog.Dial",
  240. function (e, v, m, f) {
  241. if (v) {
  242. var numberInput = f.sipNumber;
  243. if (numberInput) {
  244. APP.xmpp.dial(
  245. numberInput, 'fromnumber', UI.getRoomName(), sharedKey);
  246. }
  247. }
  248. },
  249. null, null, ':input:first'
  250. );
  251. }
  252. var Toolbar = (function (my) {
  253. my.init = function (ui) {
  254. for(var k in buttonHandlers)
  255. $("#" + k).click(buttonHandlers[k]);
  256. UI = ui;
  257. // Update login info
  258. APP.xmpp.addListener(
  259. AuthenticationEvents.IDENTITY_UPDATED,
  260. function (authenticationEnabled, userIdentity) {
  261. var loggedIn = false;
  262. if (userIdentity) {
  263. loggedIn = true;
  264. }
  265. Toolbar.showAuthenticateButton(authenticationEnabled);
  266. if (authenticationEnabled) {
  267. Toolbar.setAuthenticatedIdentity(userIdentity);
  268. Toolbar.showLoginButton(!loggedIn);
  269. Toolbar.showLogoutButton(loggedIn);
  270. }
  271. }
  272. );
  273. },
  274. /**
  275. * Sets shared key
  276. * @param sKey the shared key
  277. */
  278. my.setSharedKey = function (sKey) {
  279. sharedKey = sKey;
  280. };
  281. my.authenticateClicked = function () {
  282. Authentication.focusAuthenticationWindow();
  283. if (!APP.xmpp.isExternalAuthEnabled()) {
  284. Authentication.xmppAuthenticate();
  285. return;
  286. }
  287. // Get authentication URL
  288. if (!APP.xmpp.getMUCJoined()) {
  289. APP.xmpp.getLoginUrl(UI.getRoomName(), function (url) {
  290. // If conference has not been started yet - redirect to login page
  291. window.location.href = url;
  292. });
  293. } else {
  294. APP.xmpp.getPopupLoginUrl(UI.getRoomName(), function (url) {
  295. // Otherwise - open popup with authentication URL
  296. var authenticationWindow = Authentication.createAuthenticationWindow(
  297. function () {
  298. // On popup closed - retry room allocation
  299. APP.xmpp.allocateConferenceFocus(
  300. APP.UI.getRoomName(),
  301. function () { console.info("AUTH DONE"); }
  302. );
  303. }, url);
  304. if (!authenticationWindow) {
  305. messageHandler.openMessageDialog(
  306. null, "dialog.popupError");
  307. }
  308. });
  309. }
  310. };
  311. /**
  312. * Updates the room invite url.
  313. */
  314. my.updateRoomUrl = function (newRoomUrl) {
  315. roomUrl = newRoomUrl;
  316. // If the invite dialog has been already opened we update the information.
  317. var inviteLink = document.getElementById('inviteLinkRef');
  318. if (inviteLink) {
  319. inviteLink.value = roomUrl;
  320. inviteLink.select();
  321. $('#inviteLinkRef').parent()
  322. .find('button[value=true]').prop('disabled', false);
  323. }
  324. };
  325. /**
  326. * Disables and enables some of the buttons.
  327. */
  328. my.setupButtonsFromConfig = function () {
  329. if (config.disablePrezi)
  330. {
  331. $("#prezi_button").css({display: "none"});
  332. }
  333. };
  334. /**
  335. * Opens the lock room dialog.
  336. */
  337. my.openLockDialog = function () {
  338. // Only the focus is able to set a shared key.
  339. if (!APP.xmpp.isModerator()) {
  340. if (sharedKey) {
  341. messageHandler.openMessageDialog(null,
  342. "dialog.passwordError");
  343. } else {
  344. messageHandler.openMessageDialog(null, "dialog.passwordError2");
  345. }
  346. } else {
  347. if (sharedKey) {
  348. messageHandler.openTwoButtonDialog(null, null,
  349. "dialog.passwordCheck",
  350. null,
  351. false,
  352. "dialog.Remove",
  353. function (e, v) {
  354. if (v) {
  355. Toolbar.setSharedKey('');
  356. lockRoom(false);
  357. }
  358. });
  359. } else {
  360. var msg = APP.translation.generateTranslatonHTML(
  361. "dialog.passwordMsg");
  362. var yourPassword = APP.translation.translateString(
  363. "dialog.yourPassword");
  364. messageHandler.openTwoButtonDialog(null, null, null,
  365. '<h2>' + msg + '</h2>' +
  366. '<input name="lockKey" type="text"' +
  367. ' data-i18n="[placeholder]dialog.yourPassword" ' +
  368. 'placeholder="' + yourPassword + '" autofocus>',
  369. false,
  370. "dialog.Save",
  371. function (e, v, m, f) {
  372. if (v) {
  373. var lockKey = f.lockKey;
  374. if (lockKey) {
  375. Toolbar.setSharedKey(
  376. UIUtil.escapeHtml(lockKey));
  377. lockRoom(true);
  378. }
  379. }
  380. },
  381. null, null, 'input:first'
  382. );
  383. }
  384. }
  385. };
  386. /**
  387. * Opens the invite link dialog.
  388. */
  389. my.openLinkDialog = function () {
  390. var inviteAttreibutes;
  391. if (roomUrl === null) {
  392. inviteAttreibutes = 'data-i18n="[value]roomUrlDefaultMsg" value="' +
  393. APP.translation.translateString("roomUrlDefaultMsg") + '"';
  394. } else {
  395. inviteAttreibutes = "value=\"" + encodeURI(roomUrl) + "\"";
  396. }
  397. messageHandler.openTwoButtonDialog("dialog.shareLink",
  398. null, null,
  399. '<input id="inviteLinkRef" type="text" ' +
  400. inviteAttreibutes + ' onclick="this.select();" readonly>',
  401. false,
  402. "dialog.Invite",
  403. function (e, v) {
  404. if (v) {
  405. if (roomUrl) {
  406. inviteParticipants();
  407. }
  408. }
  409. },
  410. function (event) {
  411. if (roomUrl) {
  412. document.getElementById('inviteLinkRef').select();
  413. } else {
  414. if (event && event.target)
  415. $(event.target)
  416. .find('button[value=true]').prop('disabled', true);
  417. }
  418. }
  419. );
  420. };
  421. /**
  422. * Opens the settings dialog.
  423. * FIXME: not used ?
  424. */
  425. my.openSettingsDialog = function () {
  426. var settings1 = APP.translation.generateTranslatonHTML(
  427. "dialog.settings1");
  428. var settings2 = APP.translation.generateTranslatonHTML(
  429. "dialog.settings2");
  430. var settings3 = APP.translation.generateTranslatonHTML(
  431. "dialog.settings3");
  432. var yourPassword = APP.translation.translateString(
  433. "dialog.yourPassword");
  434. messageHandler.openTwoButtonDialog(null,
  435. '<h2>' + settings1 + '</h2>' +
  436. '<input type="checkbox" id="initMuted">' +
  437. settings2 + '<br/>' +
  438. '<input type="checkbox" id="requireNicknames">' +
  439. settings3 +
  440. '<input id="lockKey" type="text" placeholder="' + yourPassword +
  441. '" data-i18n="[placeholder]dialog.yourPassword" autofocus>',
  442. null,
  443. null,
  444. false,
  445. "dialog.Save",
  446. function () {
  447. document.getElementById('lockKey').focus();
  448. },
  449. function (e, v) {
  450. if (v) {
  451. if ($('#initMuted').is(":checked")) {
  452. // it is checked
  453. }
  454. if ($('#requireNicknames').is(":checked")) {
  455. // it is checked
  456. }
  457. /*
  458. var lockKey = document.getElementById('lockKey');
  459. if (lockKey.value) {
  460. setSharedKey(lockKey.value);
  461. lockRoom(true);
  462. }
  463. */
  464. }
  465. }
  466. );
  467. };
  468. /**
  469. * Toggles the application in and out of full screen mode
  470. * (a.k.a. presentation mode in Chrome).
  471. */
  472. my.toggleFullScreen = function () {
  473. var fsElement = document.documentElement;
  474. if (!document.mozFullScreen && !document.webkitIsFullScreen) {
  475. //Enter Full Screen
  476. if (fsElement.mozRequestFullScreen) {
  477. fsElement.mozRequestFullScreen();
  478. }
  479. else {
  480. fsElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
  481. }
  482. } else {
  483. //Exit Full Screen
  484. if (document.mozCancelFullScreen) {
  485. document.mozCancelFullScreen();
  486. } else {
  487. document.webkitCancelFullScreen();
  488. }
  489. }
  490. };
  491. /**
  492. * Unlocks the lock button state.
  493. */
  494. my.unlockLockButton = function () {
  495. if ($("#lockIcon").hasClass("icon-security-locked"))
  496. UIUtil.buttonClick("#lockIcon", "icon-security icon-security-locked");
  497. };
  498. /**
  499. * Updates the lock button state to locked.
  500. */
  501. my.lockLockButton = function () {
  502. if ($("#lockIcon").hasClass("icon-security"))
  503. UIUtil.buttonClick("#lockIcon", "icon-security icon-security-locked");
  504. };
  505. /**
  506. * Shows or hides authentication button
  507. * @param show <tt>true</tt> to show or <tt>false</tt> to hide
  508. */
  509. my.showAuthenticateButton = function (show) {
  510. if (show) {
  511. $('#authentication').css({display: "inline"});
  512. }
  513. else {
  514. $('#authentication').css({display: "none"});
  515. }
  516. };
  517. // Shows or hides the 'recording' button.
  518. my.showRecordingButton = function (show) {
  519. if (!config.enableRecording) {
  520. return;
  521. }
  522. if (show) {
  523. $('#recording').css({display: "inline"});
  524. }
  525. else {
  526. $('#recording').css({display: "none"});
  527. }
  528. };
  529. // Sets the state of the recording button
  530. my.setRecordingButtonState = function (isRecording) {
  531. var selector = $('#recordButton');
  532. if (isRecording) {
  533. selector.removeClass("icon-recEnable");
  534. selector.addClass("icon-recEnable active");
  535. } else {
  536. selector.removeClass("icon-recEnable active");
  537. selector.addClass("icon-recEnable");
  538. }
  539. };
  540. // Shows or hides SIP calls button
  541. my.showSipCallButton = function (show) {
  542. if (APP.xmpp.isSipGatewayEnabled() && show) {
  543. $('#sipCallButton').css({display: "inline-block"});
  544. } else {
  545. $('#sipCallButton').css({display: "none"});
  546. }
  547. };
  548. // Shows or hides the dialpad button
  549. my.showDialPadButton = function (show) {
  550. if (show) {
  551. $('#dialPadButton').css({display: "inline-block"});
  552. } else {
  553. $('#dialPadButton').css({display: "none"});
  554. }
  555. };
  556. /**
  557. * Displays user authenticated identity name(login).
  558. * @param authIdentity identity name to be displayed.
  559. */
  560. my.setAuthenticatedIdentity = function (authIdentity) {
  561. if (authIdentity) {
  562. var selector = $('#toolbar_auth_identity');
  563. selector.css({display: "list-item"});
  564. selector.text(authIdentity);
  565. } else {
  566. $('#toolbar_auth_identity').css({display: "none"});
  567. }
  568. };
  569. /**
  570. * Shows/hides login button.
  571. * @param show <tt>true</tt> to show
  572. */
  573. my.showLoginButton = function (show) {
  574. if (show) {
  575. $('#toolbar_button_login').css({display: "list-item"});
  576. } else {
  577. $('#toolbar_button_login').css({display: "none"});
  578. }
  579. };
  580. /**
  581. * Shows/hides logout button.
  582. * @param show <tt>true</tt> to show
  583. */
  584. my.showLogoutButton = function (show) {
  585. if (show) {
  586. $('#toolbar_button_logout').css({display: "list-item"});
  587. } else {
  588. $('#toolbar_button_logout').css({display: "none"});
  589. }
  590. };
  591. /**
  592. * Sets the state of the button. The button has blue glow if desktop
  593. * streaming is active.
  594. * @param active the state of the desktop streaming.
  595. */
  596. my.changeDesktopSharingButtonState = function (active) {
  597. var button = $("#desktopsharing > a");
  598. if (active)
  599. {
  600. button.addClass("glow");
  601. }
  602. else
  603. {
  604. button.removeClass("glow");
  605. }
  606. };
  607. return my;
  608. }(Toolbar || {}));
  609. module.exports = Toolbar;