Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /* global APP, $, config, interfaceConfig */
  2. /* jshint -W101 */
  3. import UIUtil from '../util/UIUtil';
  4. import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
  5. import UIEvents from '../../../service/UI/UIEvents';
  6. let roomUrl = null;
  7. let emitter = null;
  8. /**
  9. * Opens the invite link dialog.
  10. */
  11. function openLinkDialog () {
  12. let inviteAttributes;
  13. if (roomUrl === null) {
  14. inviteAttributes = 'data-i18n="[value]roomUrlDefaultMsg" value="' +
  15. APP.translation.translateString("roomUrlDefaultMsg") + '"';
  16. } else {
  17. inviteAttributes = "value=\"" + encodeURI(roomUrl) + "\"";
  18. }
  19. APP.UI.messageHandler.openTwoButtonDialog(
  20. "dialog.shareLink", null, null,
  21. `<input id="inviteLinkRef" type="text" ${inviteAttributes} onclick="this.select();" readonly>`,
  22. false, "dialog.Invite",
  23. function (e, v) {
  24. if (v && roomUrl) {
  25. AnalyticsAdapter.sendEvent('toolbar.invite.button');
  26. emitter.emit(UIEvents.USER_INVITED, roomUrl);
  27. }
  28. else {
  29. AnalyticsAdapter.sendEvent('toolbar.invite.cancel');
  30. }
  31. },
  32. function (event) {
  33. if (roomUrl) {
  34. document.getElementById('inviteLinkRef').select();
  35. } else {
  36. if (event && event.target) {
  37. $(event.target).find('button[value=true]').prop('disabled', true);
  38. }
  39. }
  40. },
  41. function (e, v, m, f) {
  42. if(!v && !m && !f)
  43. AnalyticsAdapter.sendEvent('toolbar.invite.close');
  44. }
  45. );
  46. }
  47. const buttonHandlers = {
  48. "toolbar_button_mute": function () {
  49. let sharedVideoManager = APP.UI.getSharedVideoManager();
  50. if (APP.conference.audioMuted) {
  51. // If there's a shared video with the volume "on" and we aren't
  52. // the video owner, we warn the user
  53. // that currently it's not possible to unmute.
  54. if (sharedVideoManager
  55. && sharedVideoManager.isSharedVideoVolumeOn()
  56. && !sharedVideoManager.isSharedVideoOwner()) {
  57. UIUtil.animateShowElement(
  58. $("#unableToUnmutePopup"), true, 5000);
  59. }
  60. else {
  61. AnalyticsAdapter.sendEvent('toolbar.audio.unmuted');
  62. emitter.emit(UIEvents.AUDIO_MUTED, false, true);
  63. }
  64. } else {
  65. AnalyticsAdapter.sendEvent('toolbar.audio.muted');
  66. emitter.emit(UIEvents.AUDIO_MUTED, true, true);
  67. }
  68. },
  69. "toolbar_button_camera": function () {
  70. if (APP.conference.videoMuted) {
  71. AnalyticsAdapter.sendEvent('toolbar.video.enabled');
  72. emitter.emit(UIEvents.VIDEO_MUTED, false);
  73. } else {
  74. AnalyticsAdapter.sendEvent('toolbar.video.disabled');
  75. emitter.emit(UIEvents.VIDEO_MUTED, true);
  76. }
  77. },
  78. "toolbar_button_security": function () {
  79. AnalyticsAdapter.sendEvent('toolbar.lock.clicked');
  80. emitter.emit(UIEvents.ROOM_LOCK_CLICKED);
  81. },
  82. "toolbar_button_link": function () {
  83. AnalyticsAdapter.sendEvent('toolbar.invite.clicked');
  84. openLinkDialog();
  85. },
  86. "toolbar_button_chat": function () {
  87. AnalyticsAdapter.sendEvent('toolbar.chat.toggled');
  88. emitter.emit(UIEvents.TOGGLE_CHAT);
  89. },
  90. "toolbar_button_etherpad": function () {
  91. AnalyticsAdapter.sendEvent('toolbar.etherpad.clicked');
  92. emitter.emit(UIEvents.ETHERPAD_CLICKED);
  93. },
  94. "toolbar_button_sharedvideo": function () {
  95. AnalyticsAdapter.sendEvent('toolbar.sharedvideo.clicked');
  96. emitter.emit(UIEvents.SHARED_VIDEO_CLICKED);
  97. },
  98. "toolbar_button_desktopsharing": function () {
  99. if (APP.conference.isSharingScreen) {
  100. AnalyticsAdapter.sendEvent('toolbar.screen.disabled');
  101. } else {
  102. AnalyticsAdapter.sendEvent('toolbar.screen.enabled');
  103. }
  104. emitter.emit(UIEvents.TOGGLE_SCREENSHARING);
  105. },
  106. "toolbar_button_fullScreen": function() {
  107. AnalyticsAdapter.sendEvent('toolbar.fullscreen.enabled');
  108. UIUtil.buttonClick("#toolbar_button_fullScreen", "icon-full-screen icon-exit-full-screen");
  109. emitter.emit(UIEvents.FULLSCREEN_TOGGLE);
  110. },
  111. "toolbar_button_sip": function () {
  112. AnalyticsAdapter.sendEvent('toolbar.sip.clicked');
  113. showSipNumberInput();
  114. },
  115. "toolbar_button_dialpad": function () {
  116. AnalyticsAdapter.sendEvent('toolbar.sip.dialpad.clicked');
  117. dialpadButtonClicked();
  118. },
  119. "toolbar_button_settings": function () {
  120. AnalyticsAdapter.sendEvent('toolbar.settings.toggled');
  121. emitter.emit(UIEvents.TOGGLE_SETTINGS);
  122. },
  123. "toolbar_button_hangup": function () {
  124. AnalyticsAdapter.sendEvent('toolbar.hangup');
  125. emitter.emit(UIEvents.HANGUP);
  126. },
  127. "toolbar_button_login": function () {
  128. AnalyticsAdapter.sendEvent('toolbar.authenticate.login.clicked');
  129. emitter.emit(UIEvents.AUTH_CLICKED);
  130. },
  131. "toolbar_button_logout": function () {
  132. AnalyticsAdapter.sendEvent('toolbar.authenticate.logout.clicked');
  133. // Ask for confirmation
  134. APP.UI.messageHandler.openTwoButtonDialog(
  135. "dialog.logoutTitle",
  136. null,
  137. "dialog.logoutQuestion",
  138. null,
  139. false,
  140. "dialog.Yes",
  141. function (evt, yes) {
  142. if (yes) {
  143. emitter.emit(UIEvents.LOGOUT);
  144. }
  145. }
  146. );
  147. }
  148. };
  149. const defaultToolbarButtons = {
  150. 'microphone': '#toolbar_button_mute',
  151. 'camera': '#toolbar_button_camera',
  152. 'desktop': '#toolbar_button_desktopsharing',
  153. 'security': '#toolbar_button_security',
  154. 'invite': '#toolbar_button_link',
  155. 'chat': '#toolbar_button_chat',
  156. 'etherpad': '#toolbar_button_etherpad',
  157. 'fullscreen': '#toolbar_button_fullScreen',
  158. 'settings': '#toolbar_button_settings',
  159. 'hangup': '#toolbar_button_hangup'
  160. };
  161. function dialpadButtonClicked() {
  162. //TODO show the dialpad box
  163. }
  164. function showSipNumberInput () {
  165. let defaultNumber = config.defaultSipNumber
  166. ? config.defaultSipNumber
  167. : '';
  168. let sipMsg = APP.translation.generateTranslationHTML("dialog.sipMsg");
  169. APP.UI.messageHandler.openTwoButtonDialog(
  170. null, null, null,
  171. `<h2>${sipMsg}</h2>
  172. <input name="sipNumber" type="text" value="${defaultNumber}" autofocus>`,
  173. false, "dialog.Dial",
  174. function (e, v, m, f) {
  175. if (v && f.sipNumber) {
  176. emitter.emit(UIEvents.SIP_DIAL, f.sipNumber);
  177. }
  178. },
  179. null, null, ':input:first'
  180. );
  181. }
  182. const Toolbar = {
  183. init (eventEmitter) {
  184. emitter = eventEmitter;
  185. // The toolbar is enabled by default.
  186. this.enabled = true;
  187. this.toolbarSelector = $("#header");
  188. UIUtil.hideDisabledButtons(defaultToolbarButtons);
  189. Object.keys(buttonHandlers).forEach(
  190. buttonId => $(`#${buttonId}`).click(function(event) {
  191. !$(this).prop('disabled') && buttonHandlers[buttonId](event);
  192. })
  193. );
  194. },
  195. /**
  196. * Enables / disables the toolbar.
  197. * @param {e} set to {true} to enable the toolbar or {false}
  198. * to disable it
  199. */
  200. enable (e) {
  201. this.enabled = e;
  202. if (!e && this.isVisible())
  203. this.hide(false);
  204. },
  205. /**
  206. * Indicates if the bottom toolbar is currently enabled.
  207. * @return {this.enabled}
  208. */
  209. isEnabled() {
  210. return this.enabled;
  211. },
  212. /**
  213. * Updates the room invite url.
  214. */
  215. updateRoomUrl (newRoomUrl) {
  216. roomUrl = newRoomUrl;
  217. // If the invite dialog has been already opened we update the
  218. // information.
  219. let inviteLink = document.getElementById('inviteLinkRef');
  220. if (inviteLink) {
  221. inviteLink.value = roomUrl;
  222. inviteLink.select();
  223. $('#inviteLinkRef').parent()
  224. .find('button[value=true]').prop('disabled', false);
  225. }
  226. },
  227. /**
  228. * Unlocks the lock button state.
  229. */
  230. unlockLockButton () {
  231. if ($("#toolbar_button_security").hasClass("icon-security-locked"))
  232. UIUtil.buttonClick("#toolbar_button_security",
  233. "icon-security icon-security-locked");
  234. },
  235. /**
  236. * Updates the lock button state to locked.
  237. */
  238. lockLockButton () {
  239. if ($("#toolbar_button_security").hasClass("icon-security"))
  240. UIUtil.buttonClick("#toolbar_button_security",
  241. "icon-security icon-security-locked");
  242. },
  243. /**
  244. * Shows or hides authentication button
  245. * @param show <tt>true</tt> to show or <tt>false</tt> to hide
  246. */
  247. showAuthenticateButton (show) {
  248. if (UIUtil.isButtonEnabled('authentication') && show) {
  249. $('#authentication').css({display: "inline"});
  250. } else {
  251. $('#authentication').css({display: "none"});
  252. }
  253. },
  254. showEtherpadButton () {
  255. if (!$('#toolbar_button_etherpad').is(":visible")) {
  256. $('#toolbar_button_etherpad').css({display: 'inline-block'});
  257. }
  258. },
  259. // Shows or hides the 'shared video' button.
  260. showSharedVideoButton () {
  261. if (UIUtil.isButtonEnabled('sharedvideo')
  262. && config.disableThirdPartyRequests !== true) {
  263. $('#toolbar_button_sharedvideo').css({display: "inline-block"});
  264. } else {
  265. $('#toolbar_button_sharedvideo').css({display: "none"});
  266. }
  267. },
  268. // checks whether desktop sharing is enabled and whether
  269. // we have params to start automatically sharing
  270. checkAutoEnableDesktopSharing () {
  271. if (UIUtil.isButtonEnabled('desktop')
  272. && config.autoEnableDesktopSharing) {
  273. emitter.emit(UIEvents.TOGGLE_SCREENSHARING);
  274. }
  275. },
  276. // Shows or hides SIP calls button
  277. showSipCallButton (show) {
  278. if (APP.conference.sipGatewayEnabled()
  279. && UIUtil.isButtonEnabled('sip') && show) {
  280. $('#toolbar_button_sip').css({display: "inline-block"});
  281. } else {
  282. $('#toolbar_button_sip').css({display: "none"});
  283. }
  284. },
  285. // Shows or hides the dialpad button
  286. showDialPadButton (show) {
  287. if (UIUtil.isButtonEnabled('dialpad') && show) {
  288. $('#toolbar_button_dialpad').css({display: "inline-block"});
  289. } else {
  290. $('#toolbar_button_dialpad').css({display: "none"});
  291. }
  292. },
  293. /**
  294. * Displays user authenticated identity name(login).
  295. * @param authIdentity identity name to be displayed.
  296. */
  297. setAuthenticatedIdentity (authIdentity) {
  298. if (authIdentity) {
  299. let selector = $('#toolbar_auth_identity');
  300. selector.css({display: "list-item"});
  301. selector.text(authIdentity);
  302. } else {
  303. $('#toolbar_auth_identity').css({display: "none"});
  304. }
  305. },
  306. /**
  307. * Shows/hides login button.
  308. * @param show <tt>true</tt> to show
  309. */
  310. showLoginButton (show) {
  311. if (UIUtil.isButtonEnabled('authentication') && show) {
  312. $('#toolbar_button_login').css({display: "list-item"});
  313. } else {
  314. $('#toolbar_button_login').css({display: "none"});
  315. }
  316. },
  317. /**
  318. * Shows/hides logout button.
  319. * @param show <tt>true</tt> to show
  320. */
  321. showLogoutButton (show) {
  322. if (UIUtil.isButtonEnabled('authentication') && show) {
  323. $('#toolbar_button_logout').css({display: "list-item"});
  324. } else {
  325. $('#toolbar_button_logout').css({display: "none"});
  326. }
  327. },
  328. /**
  329. * Update the state of the button. The button has blue glow if desktop
  330. * streaming is active.
  331. */
  332. updateDesktopSharingButtonState () {
  333. let button = $("#toolbar_button_desktopsharing");
  334. if (APP.conference.isSharingScreen) {
  335. button.addClass("glow");
  336. } else {
  337. button.removeClass("glow");
  338. }
  339. },
  340. /**
  341. * Marks video icon as muted or not.
  342. * @param {boolean} muted if icon should look like muted or not
  343. */
  344. markVideoIconAsMuted (muted) {
  345. $('#toolbar_button_camera').toggleClass("icon-camera-disabled", muted);
  346. },
  347. /**
  348. * Marks video icon as disabled or not.
  349. * @param {boolean} disabled if icon should look like disabled or not
  350. */
  351. markVideoIconAsDisabled (disabled) {
  352. var $btn = $('#toolbar_button_camera');
  353. $btn
  354. .prop("disabled", disabled)
  355. .attr("data-i18n", disabled
  356. ? "[content]toolbar.cameraDisabled"
  357. : "[content]toolbar.videomute")
  358. .attr("shortcut", disabled ? "" : "toggleVideoPopover");
  359. disabled
  360. ? $btn.attr("disabled", "disabled")
  361. : $btn.removeAttr("disabled");
  362. APP.translation.translateElement($btn);
  363. disabled && this.markVideoIconAsMuted(disabled);
  364. },
  365. /**
  366. * Marks audio icon as muted or not.
  367. * @param {boolean} muted if icon should look like muted or not
  368. */
  369. markAudioIconAsMuted (muted) {
  370. $('#toolbar_button_mute').toggleClass("icon-microphone",
  371. !muted).toggleClass("icon-mic-disabled", muted);
  372. },
  373. /**
  374. * Marks audio icon as disabled or not.
  375. * @param {boolean} disabled if icon should look like disabled or not
  376. */
  377. markAudioIconAsDisabled (disabled) {
  378. var $btn = $('#toolbar_button_mute');
  379. $btn
  380. .prop("disabled", disabled)
  381. .attr("data-i18n", disabled
  382. ? "[content]toolbar.micDisabled"
  383. : "[content]toolbar.mute")
  384. .attr("shortcut", disabled ? "" : "mutePopover");
  385. disabled
  386. ? $btn.attr("disabled", "disabled")
  387. : $btn.removeAttr("disabled");
  388. APP.translation.translateElement($btn);
  389. disabled && this.markAudioIconAsMuted(disabled);
  390. },
  391. /**
  392. * Indicates if the toolbar is currently hovered.
  393. * @return {true} if the toolbar is currently hovered, {false} otherwise
  394. */
  395. isHovered() {
  396. this.toolbarSelector.find('*').each(function () {
  397. let id = $(this).attr('id');
  398. if ($(`#${id}:hover`).length > 0) {
  399. return true;
  400. }
  401. });
  402. if ($("#bottomToolbar:hover").length > 0) {
  403. return true;
  404. }
  405. return false;
  406. },
  407. /**
  408. * Returns true if this toolbar is currently visible, or false otherwise.
  409. * @return <tt>true</tt> if currently visible, <tt>false</tt> - otherwise
  410. */
  411. isVisible() {
  412. return this.toolbarSelector.is(":visible");
  413. },
  414. /**
  415. * Hides the toolbar with animation or not depending on the animate
  416. * parameter.
  417. */
  418. hide() {
  419. this.toolbarSelector.hide(
  420. "slide", { direction: "up", duration: 300});
  421. },
  422. /**
  423. * Shows the toolbar with animation or not depending on the animate
  424. * parameter.
  425. */
  426. show() {
  427. this.toolbarSelector.show(
  428. "slide", { direction: "up", duration: 300});
  429. }
  430. };
  431. export default Toolbar;